security क्या "डबल हैशिंग" एक बार पासवर्ड को कम से कम एक बार सुरक्षित करने से सुरक्षित है?




hash passwords (13)

भंडारण से पहले दो बार पासवर्ड धोना किसी भी कम या ज्यादा सुरक्षित है, इसे सिर्फ एक बार हैश करना?

मैं किस बारे में बात कर रहा हूं यह कर रहा है:

$hashed_password = hash(hash($plaintext_password));

बस इसके बजाय:

$hashed_password = hash($plaintext_password);

यदि यह कम सुरक्षित है, तो क्या आप एक अच्छी व्याख्या (या एक लिंक) प्रदान कर सकते हैं?

साथ ही, हैश फ़ंक्शन का उपयोग करने में कोई फर्क पड़ता है? यदि आप उसी हैश फ़ंक्शन को दोहराने के बजाय md5 और sha1 (उदाहरण के लिए) मिश्रण करते हैं तो इससे कोई फर्क पड़ता है?

नोट 1: जब मैं "डबल हैशिंग" कहता हूं, तो मैं इसे अधिक अस्पष्ट बनाने के प्रयास में दो बार पासवर्ड धोने के बारे में बात कर रहा हूं। मैं टकराव को हल करने के लिए तकनीक के बारे में बात नहीं कर रहा हूं।

नोट 2: मुझे पता है कि मुझे वास्तव में इसे सुरक्षित बनाने के लिए यादृच्छिक नमक जोड़ने की आवश्यकता है। सवाल यह है कि क्या एक ही एल्गोरिदम के साथ दो बार हैशिंग हैश को मदद या दर्द देता है।


हाँ।

Absolutely do not use multiple iterations of a conventional hash function, like md5(md5(md5(password))) . At best you will be getting a marginal increase in security (a scheme like this offers hardly any protection against a GPU attack; just pipeline it.) At worst, you're reducing your hash space (and thus security) with every iteration you add. In security, it's wise to assume the worst.

Do use a password has that's been designed by a competent cryptographer to be an effective password hash, and resistant to both brute-force and time-space attacks. These include bcrypt, scrypt, and in some situations PBKDF2. The glibc SHA-256-based hash is also acceptable.


As several responses in this article suggest, there are some cases where it may improves security and others where it definately hurts it. There is a better solution that will definately improve security. Instead of doubling the number of times you calculate the hash, double the size of your salt, or double the number of bits used int the hash, or do both! Instead of SHA-245, jump up to SHA-512.


Double hashing makes sense to me only if I hash the password on the client, and then save the hash (with different salt) of that hash on the server.

That way even if someone hacked his way into the server (thereby ignoring the safety SSL provides), he still can't get to the clear passwords.

Yes he will have the data required to breach into the system, but he wouldn't be able to use that data to compromise outside accounts the user has. And people are known to use the same password for virtually anything.

The only way he could get to the clear passwords is installing a keygen on the client - and that's not your problem anymore.

तो संक्षेप में:

  1. The first hashing on the client protects your users in a 'server breach' scenario.
  2. The second hashing on the server serves to protect your system if someone got a hold of your database backup, so he can't use those passwords to connect to your services.

हां, पुनः-हैशिंग खोज स्थान को कम कर देता है, लेकिन नहीं, इससे कोई फर्क नहीं पड़ता - प्रभावी कमी महत्वहीन है।

री-हैशिंग उस समय को बढ़ा देती है जो इसे ब्रूट-फोर्स में ले जाती है, लेकिन ऐसा करने से केवल दो बार उप-स्थानिक होता है।

आप वास्तव में क्या चाहते हैं कि PBKDF2 साथ पासवर्ड हैश - नमक और पुनरावृत्तियों के साथ एक सुरक्षित हैश का उपयोग करने का एक सिद्ध तरीका है। यह SO प्रतिक्रिया देखें

संपादित करें : मैं लगभग भूल गया - MD5 का उपयोग न करें !!!! एक आधुनिक क्रिप्टोग्राफिक हैश का उपयोग करें जैसे SHA-2 परिवार (SHA-256, SHA-384, और SHA-512)।


Most answers are by people without a background in cryptography or security. And they are wrong. Use a salt, if possible unique per record. MD5/SHA/etc are too fast, the opposite of what you want. PBKDF2 and bcrypt are slower (wich is good) but can be defeated with ASICs/FPGA/GPUs (very afordable nowadays). So a memory-hard algorithm is needed: enter scrypt .

Here's a layman explanation on salts and speed (but not about memory-hard algorithms).


In general, it provides no additional security to double hash or double encrypt something. If you can break the hash once, you can break it again. It usually doesn't hurt security to do this, though.

In your example of using MD5, as you probably know there are some collision issues. "Double Hashing" doesn't really help protect against this, since the same collisions will still result in the same first hash, which you can then MD5 again to get the second hash.

This does protect against dictionary attacks, like those "reverse MD5-databases", but so does salting.

On a tangent, Double encrypting something doesn't provide any additional security because all it does is result in a different key which is a combination of the two keys actually used. So the effort to find the "key" is not doubled because two keys do not actually need to be found. This isn't true for hashing, because the result of the hash is not usually the same length as the original input.


एक बार पासवर्ड धोना असुरक्षित है

नहीं, एकाधिक हैंश कम सुरक्षित नहीं हैं; वे सुरक्षित पासवर्ड उपयोग का एक अनिवार्य हिस्सा हैं।

हैश को घुमाने में हमलावर के लिए उम्मीदवारों की सूची में प्रत्येक पासवर्ड का प्रयास करने में लगने वाला समय बढ़ जाता है। आप घंटों से सालों तक पासवर्ड पर हमला करने में लगने वाले समय को आसानी से बढ़ा सकते हैं।

सरल पुनरावृत्ति पर्याप्त नहीं है

इनपुट के लिए केवल चेन हैश आउटपुट सुरक्षा के लिए पर्याप्त नहीं है। पुनरावृत्ति एक एल्गोरिदम के संदर्भ में होनी चाहिए जो पासवर्ड की एन्ट्रॉपी को सुरक्षित रखती है। सौभाग्य से, कई प्रकाशित एल्गोरिदम हैं जिनके डिजाइन में विश्वास देने के लिए पर्याप्त जांच है।

पीबीकेडीएफ 2 की तरह एक अच्छी कुंजी व्युत्पन्न एल्गोरिदम हैशिंग के प्रत्येक दौर में पासवर्ड इंजेक्ट करता है, हैश आउटपुट में टकराव के बारे में चिंताओं को कम करता है। पासवर्ड प्रमाणीकरण के लिए पीबीकेडीएफ 2 का उपयोग किया जा सकता है। Bcrypt एक एन्क्रिप्शन चरण के साथ मुख्य व्युत्पन्न का पालन करता है; इस तरह, यदि मुख्य व्युत्पन्न को उलटने का एक तेज़ तरीका खोजा गया है, तो एक हमलावर को अभी भी एक ज्ञात-सादे पाठ हमले को पूरा करना होगा।

पासवर्ड कैसे तोड़ें

संग्रहीत पासवर्ड को ऑफ़लाइन हमले से सुरक्षा की आवश्यकता होती है। यदि पासवर्ड नमकीन नहीं होते हैं, तो उन्हें पूर्व-गणना वाले शब्दकोश हमले के साथ तोड़ा जा सकता है (उदाहरण के लिए, इंद्रधनुष तालिका का उपयोग करके)। अन्यथा, हमलावर को प्रत्येक पासवर्ड के लिए हैश की गणना करने के लिए समय बिताना चाहिए और देखें कि यह संग्रहीत हैश से मेल खाता है या नहीं।

सभी पासवर्ड समान रूप से संभव नहीं हैं। हमलावर पूरी तरह से सभी छोटे पासवर्ड खोज सकते हैं, लेकिन वे जानते हैं कि क्रूर बल की सफलता के अवसर उनके अतिरिक्त चरित्र के साथ तेजी से गिरते हैं। इसके बजाय, वे सबसे संभावित पासवर्ड की एक आदेशित सूची का उपयोग करते हैं। वे "password123" से शुरू होते हैं और कम बार-बार उपयोग किए जाने वाले पासवर्ड तक प्रगति करते हैं।

आइए मान लें कि 10 बिलियन उम्मीदवारों के साथ हमलावर सूची लंबी है; मान लीजिए कि एक डेस्कटॉप सिस्टम प्रति सेकंड 1 मिलियन हैश की गणना कर सकता है। हमलावर उसकी पूरी सूची का परीक्षण कर सकता है यदि केवल एक पुनरावृत्ति का उपयोग किया जाता है तो तीन घंटे से भी कम समय तक होता है। लेकिन अगर केवल 2000 पुनरावृत्तियों का उपयोग किया जाता है, तो वह समय लगभग 8 महीने तक फैलता है। एक अधिक परिष्कृत हमलावर को हराने के लिए - एक प्रोग्राम डाउनलोड करने में सक्षम जो अपने जीपीयू की शक्ति को टैप कर सकता है, उदाहरण के लिए- आपको अधिक पुनरावृत्तियों की आवश्यकता है।

कितना काफी है?

उपयोग करने के लिए पुनरावृत्तियों की संख्या सुरक्षा और उपयोगकर्ता अनुभव के बीच एक व्यापार बंद है। हमलावरों द्वारा उपयोग किए जाने वाले विशिष्ट हार्डवेयर सस्ते हैं, लेकिन यह अभी भी प्रति सेकेंड लाखों पुनरावृत्तियों का प्रदर्शन कर सकता है। हमलावर की प्रणाली का प्रदर्शन यह निर्धारित करता है कि कई पुनरावृत्तियों के बाद पासवर्ड को तोड़ने में कितना समय लगता है। लेकिन आपके एप्लिकेशन को इस विशेष हार्डवेयर का उपयोग करने की संभावना नहीं है। बढ़ते उपयोगकर्ताओं के बिना आप कितने पुनरावृत्तियों का प्रदर्शन कर सकते हैं आपके सिस्टम पर निर्भर करता है।

आप शायद प्रमाणीकरण के दौरान उपयोगकर्ताओं को एक अतिरिक्त ¾ दूसरा या तो इंतजार कर सकते हैं। अपने लक्षित प्लेटफार्म को प्रोफाइल करें, और जितना आप कर सकते हैं उतने पुनरावृत्तियों का उपयोग करें। मैंने जिन प्लेटफॉर्म का परीक्षण किया है (मोबाइल डिवाइस पर एक उपयोगकर्ता, या सर्वर प्लेटफॉर्म पर कई उपयोगकर्ता) आसानी से bcrypt PBKDF2 समर्थन 60,000 से 120,000 पुनरावृत्तियों के साथ कर सकते हैं, या 12 या 13 के लागत कारक के साथ bcrypt कर सकते हैं।

अधिक पृष्ठभूमि

हैशिंग में नमक और पुनरावृत्तियों की भूमिका पर आधिकारिक जानकारी के लिए पीकेसीएस # 5 पढ़ें। भले ही पीबीकेडीएफ 2 पासवर्ड से एन्क्रिप्शन कुंजी उत्पन्न करने के लिए था, यह पासवर्ड प्रमाणीकरण के लिए एक तरफा हैश के रूप में अच्छी तरह से काम करता है। Bcrypt का प्रत्येक पुनरावृत्ति SHA-2 हैश से अधिक महंगा है, इसलिए आप कम पुनरावृत्तियों का उपयोग कर सकते हैं, लेकिन विचार समान है। Bcrypt एक प्रसिद्ध सादे पाठ को एन्क्रिप्ट करने के लिए व्युत्पन्न कुंजी का उपयोग करके अधिकांश पीबीकेडीएफ 2-आधारित समाधानों से परे एक कदम भी चला जाता है। परिणामी सिफर टेक्स्ट कुछ मेटा-डेटा के साथ "हैश" के रूप में संग्रहीत किया जाता है। हालांकि, कुछ भी आपको पीबीकेडीएफ 2 के साथ एक ही चीज़ करने से रोकता है।

इस विषय पर मैंने जो अन्य उत्तर लिखे हैं, वे यहां दिए गए हैं:


From what I've read, it may actually be recommended to re-hash the password hundreds or thousands of times.

The idea is that if you can make it take more time to encode the password, it's more work for an attacker to run through many guesses to crack the password. That seems to be the advantage to re-hashing -- not that it's more cryptographically secure, but it simply takes longer to generate a dictionary attack.

Of course computers get faster all the time, so this advantage diminishes over time (or requires you to increase the iterations).


I just look at this from a practical standpoint. What is the hacker after? Why, the combination of characters that, when put through the hash function, generates the desired hash.

You are only saving the last hash, therefore, the hacker only has to bruteforce one hash. Assuming you have roughly the same odds of stumbling across the desired hash with each bruteforce step, the number of hashes is irrelevant. You could do a million hash iterations, and it would not increase or reduce security one bit, since at the end of the line there's still only one hash to break, and the odds of breaking it are the same as any hash.

Maybe the previous posters think that the input is relevant; it's not. As long as whatever you put into the hash function generates the desired hash, it will get you through, correct input or incorrect input.

Now, rainbow tables are another story. Since a rainbow table only carries raw passwords, hashing twice may be a good security measure, since a rainbow table that contains every hash of every hash would be too large.

Of course, I'm only considering the example the OP gave, where it's just a plain-text password being hashed. If you include the username or a salt in the hash, it's a different story; hashing twice is entirely unnecessary, since the rainbow table would already be too large to be practical and contain the right hash.

Anyway, not a security expert here, but that's just what I've figured from my experience.


Personally I wouldn't bother with multiple hashses, but I'd make sure to also hash the UserName (or another User ID field) as well as the password so two users with the same password won't end up with the same hash. Also I'd probably throw some other constant string into the input string too for good measure.

$hashed_password = md5( "xxx" + "|" + user_name + "|" + plaintext_password);

The concern about reducing the search space is mathematically correct, although the search space remains large enough that for all practical purposes (assuming you use salts), at 2^128. However, since we are talking about passwords, the number of possible 16-character strings (alphanumeric, caps matter, a few symbols thrown in) is roughly 2^98, according to my back-of-the-envelope calculations. So the perceived decrease in the search space is not really relevant.

Aside from that, there really is no difference, cryptographically speaking.

Although there is a crypto primitive called a "hash chain" -- a technique that allows you to do some cool tricks, like disclosing a signature key after it's been used, without sacrificing the integrity of the system -- given minimal time synchronization, this allows you to cleanly sidestep the problem of initial key distribution. Basically, you precompute a large set of hashes of hashes - h(h(h(h....(h(k))...))) , use the nth value to sign, after a set interval, you send out the key, and sign it using key (n-1). The recepients can now verify that you sent all the previous messages, and no one can fake your signature since the time period for which it is valid has passed.

Re-hashing hundreds of thousands of times like Bill suggests is just a waste of your cpu.. use a longer key if you are concerned about people breaking 128 bits.


Let us assume you use the hashing algorithm: compute rot13, take the first 10 characters. If you do that twice (or even 2000 times) it is possible to make a function that is faster, but which gives the same result (namely just take the first 10 chars).

Likewise it may be possible to make a faster function that gives the same output as a repeated hashing function. So your choice of hashing function is very important: as with the rot13 example it is not given that repeated hashing will improve security. If there is no research saying that the algorithm is designed for recursive use, then it is safer to assume that it will not give you added protection.

That said: For all but the simplest hashing functions it will most likely take cryptography experts to compute the faster functions, so if you are guarding against attackers that do not have access to cryptography experts it is probably safer in practice to use a repeated hashing function.


Double hashing is ugly because it's more than likely an attacker has built a table to come up with most hashes. Better is to salt your hashes, and mix hashes together. There are also new schemas to "sign" hashes (basically salting), but in a more secure manner.





password-hash