दिलचस्प पोस्ट
क्रॉस डोमेन POST अनुरोध कुकी अजाक्स Jquery भेज नहीं रहा है xmllint xpath से ठीक से क्वेरी करने में असफल रहा I पायथन में एक्सटेंशन .txt के साथ एक निर्देशिका में सभी फाइलें खोजें सी # – चुनिंदा कस्टम अप्रचलित चेतावनी को दबाएं पायथन में टाइप की जांच करने के लिए वैधानिक तरीका क्या है? आप कैसे जांचते हैं कि जावा में एक संख्या NaN है? सी # 2.0 में हैशसेट का उपयोग करते हुए, 3.5 के साथ संगत जांचें कि कोई तत्व एक सरणी में मौजूद है या नहीं जावा में घंटों / मिनट / सेकंड से युग के बाद से मैं सेकंड कैसे परिवर्तित कर सकता हूं? पैरामीटर सूची द्वारा मूल्य के आधार पर नहीं जावास्क्रिप्ट का उपयोग करते हुए XML को JSON (और बैक) में कनवर्ट करें jquery UI तालिका और tr चौड़ाई के साथ छंटनी XCode 4.x में कोड स्वत: पूर्ण / सिंटैक्स हाइलाइटिंग के साथ समस्या एक संख्या के लिए सेंट, एनडी, आरडी और वें (ऑर्डरिन) प्रत्यय जोड़ें स्थानीय सिस्टम खाते के अंतर्गत आप CMD.exe कैसे चला सकते हैं?

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

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

मैं इसके बारे में क्या कर रहा हूं:

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

इसके बजाय सिर्फ:

 $hashed_password = hash($plaintext_password); 

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

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

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

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

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

पासवर्ड को हैशिंग करना असुरक्षित है

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

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

सरल चलना पर्याप्त नहीं है

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

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

कैसे एक पासवर्ड को तोड़ने के लिए

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

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

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

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

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

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

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

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

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

  • हैशिंग पासवर्ड
  • हैशिंग पासवर्ड
  • नमक
  • नमक छुपाना
  • पीबीकेडीएफ 2 बनाम बीक्रिप्ट
  • Bcrypt

जो कहते हैं कि यह सुरक्षित है, वे सामान्य रूप से सही हैं। किसी विशिष्ट चिंता के लिए "डबल" हैशिंग (या उस के तार्किक विस्तार, एक हैश फ़ंक्शन को दोबारा करने के लिए) ठीक से सुरक्षित है।

जो लोग कहते हैं कि यह असुरक्षित है, वे इस मामले में सही हैं। प्रश्न में पोस्ट किया गया कोड असुरक्षित है। चलो क्यों बात करें:

 $hashed_password1 = md5( md5( plaintext_password ) ); $hashed_password2 = md5( plaintext_password ); 

एक हैश फ़ंक्शन के दो मौलिक गुण हैं जो हमें इसके बारे में चिंतित हैं:

  1. प्री-इमेज प्रतिरोध – एक हैश $h को देखते हुए, संदेश $m जैसे कि $h === hash($m) प्राप्त करना मुश्किल हो सकता है

  2. दूसरा प्री-इमेज प्रतिरोध – एक संदेश $m1 को देखते हुए, एक अलग संदेश $m2 जैसे कि hash($m1) === hash($m2) मिलना कठिन होना चाहिए

  3. टकराव प्रतिरोध – संदेशों की एक जोड़ी ($m1, $m2) खोजने के लिए मुश्किल होनी चाहिए जैसे कि hash($m1) === hash($m2) (ध्यान दें कि यह द्वितीय-प्री-छवि प्रतिरोध के समान है, लेकिन इसमें अलग है कि हमलावर दोनों संदेशों पर नियंत्रण रखता है) …

पासवर्ड के भंडारण के लिए , हम सभी को वास्तव में परवाह है प्री-इमेज रेजिस्टेंस । अन्य दो म्यूट होंगे, क्योंकि $m1 उपयोगकर्ता का पासवर्ड है, हम सुरक्षित रखने की कोशिश कर रहे हैं। इसलिए यदि हमलावर पहले से ही है, तो हैश की रक्षा करने के लिए कुछ नहीं है …

अस्वीकरण

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

आएँ शुरू करें

इस चर्चा के लिए, चलो हमारे अपने हीश समारोह का आविष्कार करें:

 function ourHash($input) { $result = 0; for ($i = 0; $i < strlen($input); $i++) { $result += ord($input[$i]); } return (string) ($result % 256); } 

अब यह बहुत स्पष्ट होना चाहिए कि यह हैश फ़ंक्शन क्या है। यह इनपुट के प्रत्येक चरित्र के साथ ASCII मानों का योग करता है, और फिर 256 के साथ उस परिणाम के मॉड्यूल लेता है।

तो चलो इसे जांचें:

 var_dump( ourHash('abc'), // string(2) "38" ourHash('def'), // string(2) "47" ourHash('hij'), // string(2) "59" ourHash('klm') // string(2) "68" ); 

अब, देखते हैं कि क्या होता है अगर हम इसे फ़ंक्शन के आसपास कुछ बार चलाते हैं:

 $tests = array( "abc", "def", "hij", "klm", ); foreach ($tests as $test) { $hash = $test; for ($i = 0; $i < 100; $i++) { $hash = ourHash($hash); } echo "Hashing $test => $hash\n"; } 

वह आउटपुट:

 Hashing abc => 152 Hashing def => 152 Hashing hij => 155 Hashing klm => 155 

एचआरएम, वाह हमने टकराव उत्पन्न किए हैं !!! क्यों देखने की कोशिश करते हैं:

प्रत्येक और हर संभव हैश आउटपुट की एक स्ट्रिंग हैशिंग का उत्पादन यहां है:

 Hashing 0 => 48 Hashing 1 => 49 Hashing 2 => 50 Hashing 3 => 51 Hashing 4 => 52 Hashing 5 => 53 Hashing 6 => 54 Hashing 7 => 55 Hashing 8 => 56 Hashing 9 => 57 Hashing 10 => 97 Hashing 11 => 98 Hashing 12 => 99 Hashing 13 => 100 Hashing 14 => 101 Hashing 15 => 102 Hashing 16 => 103 Hashing 17 => 104 Hashing 18 => 105 Hashing 19 => 106 Hashing 20 => 98 Hashing 21 => 99 Hashing 22 => 100 Hashing 23 => 101 Hashing 24 => 102 Hashing 25 => 103 Hashing 26 => 104 Hashing 27 => 105 Hashing 28 => 106 Hashing 29 => 107 Hashing 30 => 99 Hashing 31 => 100 Hashing 32 => 101 Hashing 33 => 102 Hashing 34 => 103 Hashing 35 => 104 Hashing 36 => 105 Hashing 37 => 106 Hashing 38 => 107 Hashing 39 => 108 Hashing 40 => 100 Hashing 41 => 101 Hashing 42 => 102 Hashing 43 => 103 Hashing 44 => 104 Hashing 45 => 105 Hashing 46 => 106 Hashing 47 => 107 Hashing 48 => 108 Hashing 49 => 109 Hashing 50 => 101 Hashing 51 => 102 Hashing 52 => 103 Hashing 53 => 104 Hashing 54 => 105 Hashing 55 => 106 Hashing 56 => 107 Hashing 57 => 108 Hashing 58 => 109 Hashing 59 => 110 Hashing 60 => 102 Hashing 61 => 103 Hashing 62 => 104 Hashing 63 => 105 Hashing 64 => 106 Hashing 65 => 107 Hashing 66 => 108 Hashing 67 => 109 Hashing 68 => 110 Hashing 69 => 111 Hashing 70 => 103 Hashing 71 => 104 Hashing 72 => 105 Hashing 73 => 106 Hashing 74 => 107 Hashing 75 => 108 Hashing 76 => 109 Hashing 77 => 110 Hashing 78 => 111 Hashing 79 => 112 Hashing 80 => 104 Hashing 81 => 105 Hashing 82 => 106 Hashing 83 => 107 Hashing 84 => 108 Hashing 85 => 109 Hashing 86 => 110 Hashing 87 => 111 Hashing 88 => 112 Hashing 89 => 113 Hashing 90 => 105 Hashing 91 => 106 Hashing 92 => 107 Hashing 93 => 108 Hashing 94 => 109 Hashing 95 => 110 Hashing 96 => 111 Hashing 97 => 112 Hashing 98 => 113 Hashing 99 => 114 Hashing 100 => 145 Hashing 101 => 146 Hashing 102 => 147 Hashing 103 => 148 Hashing 104 => 149 Hashing 105 => 150 Hashing 106 => 151 Hashing 107 => 152 Hashing 108 => 153 Hashing 109 => 154 Hashing 110 => 146 Hashing 111 => 147 Hashing 112 => 148 Hashing 113 => 149 Hashing 114 => 150 Hashing 115 => 151 Hashing 116 => 152 Hashing 117 => 153 Hashing 118 => 154 Hashing 119 => 155 Hashing 120 => 147 Hashing 121 => 148 Hashing 122 => 149 Hashing 123 => 150 Hashing 124 => 151 Hashing 125 => 152 Hashing 126 => 153 Hashing 127 => 154 Hashing 128 => 155 Hashing 129 => 156 Hashing 130 => 148 Hashing 131 => 149 Hashing 132 => 150 Hashing 133 => 151 Hashing 134 => 152 Hashing 135 => 153 Hashing 136 => 154 Hashing 137 => 155 Hashing 138 => 156 Hashing 139 => 157 Hashing 140 => 149 Hashing 141 => 150 Hashing 142 => 151 Hashing 143 => 152 Hashing 144 => 153 Hashing 145 => 154 Hashing 146 => 155 Hashing 147 => 156 Hashing 148 => 157 Hashing 149 => 158 Hashing 150 => 150 Hashing 151 => 151 Hashing 152 => 152 Hashing 153 => 153 Hashing 154 => 154 Hashing 155 => 155 Hashing 156 => 156 Hashing 157 => 157 Hashing 158 => 158 Hashing 159 => 159 Hashing 160 => 151 Hashing 161 => 152 Hashing 162 => 153 Hashing 163 => 154 Hashing 164 => 155 Hashing 165 => 156 Hashing 166 => 157 Hashing 167 => 158 Hashing 168 => 159 Hashing 169 => 160 Hashing 170 => 152 Hashing 171 => 153 Hashing 172 => 154 Hashing 173 => 155 Hashing 174 => 156 Hashing 175 => 157 Hashing 176 => 158 Hashing 177 => 159 Hashing 178 => 160 Hashing 179 => 161 Hashing 180 => 153 Hashing 181 => 154 Hashing 182 => 155 Hashing 183 => 156 Hashing 184 => 157 Hashing 185 => 158 Hashing 186 => 159 Hashing 187 => 160 Hashing 188 => 161 Hashing 189 => 162 Hashing 190 => 154 Hashing 191 => 155 Hashing 192 => 156 Hashing 193 => 157 Hashing 194 => 158 Hashing 195 => 159 Hashing 196 => 160 Hashing 197 => 161 Hashing 198 => 162 Hashing 199 => 163 Hashing 200 => 146 Hashing 201 => 147 Hashing 202 => 148 Hashing 203 => 149 Hashing 204 => 150 Hashing 205 => 151 Hashing 206 => 152 Hashing 207 => 153 Hashing 208 => 154 Hashing 209 => 155 Hashing 210 => 147 Hashing 211 => 148 Hashing 212 => 149 Hashing 213 => 150 Hashing 214 => 151 Hashing 215 => 152 Hashing 216 => 153 Hashing 217 => 154 Hashing 218 => 155 Hashing 219 => 156 Hashing 220 => 148 Hashing 221 => 149 Hashing 222 => 150 Hashing 223 => 151 Hashing 224 => 152 Hashing 225 => 153 Hashing 226 => 154 Hashing 227 => 155 Hashing 228 => 156 Hashing 229 => 157 Hashing 230 => 149 Hashing 231 => 150 Hashing 232 => 151 Hashing 233 => 152 Hashing 234 => 153 Hashing 235 => 154 Hashing 236 => 155 Hashing 237 => 156 Hashing 238 => 157 Hashing 239 => 158 Hashing 240 => 150 Hashing 241 => 151 Hashing 242 => 152 Hashing 243 => 153 Hashing 244 => 154 Hashing 245 => 155 Hashing 246 => 156 Hashing 247 => 157 Hashing 248 => 158 Hashing 249 => 159 Hashing 250 => 151 Hashing 251 => 152 Hashing 252 => 153 Hashing 253 => 154 Hashing 254 => 155 Hashing 255 => 156 

उच्च संख्या की प्रवृत्ति को ध्यान में रखें। यह हमारे घातक होने का पता चला है प्रत्येक तत्व के लिए हैश 4 बार ($ हैश = हमारा हैश ($ हैश) चलाना) हवाएं हमें दे रही हैं:

 Hashing 0 => 153 Hashing 1 => 154 Hashing 2 => 155 Hashing 3 => 156 Hashing 4 => 157 Hashing 5 => 158 Hashing 6 => 150 Hashing 7 => 151 Hashing 8 => 152 Hashing 9 => 153 Hashing 10 => 157 Hashing 11 => 158 Hashing 12 => 150 Hashing 13 => 154 Hashing 14 => 155 Hashing 15 => 156 Hashing 16 => 157 Hashing 17 => 158 Hashing 18 => 150 Hashing 19 => 151 Hashing 20 => 158 Hashing 21 => 150 Hashing 22 => 154 Hashing 23 => 155 Hashing 24 => 156 Hashing 25 => 157 Hashing 26 => 158 Hashing 27 => 150 Hashing 28 => 151 Hashing 29 => 152 Hashing 30 => 150 Hashing 31 => 154 Hashing 32 => 155 Hashing 33 => 156 Hashing 34 => 157 Hashing 35 => 158 Hashing 36 => 150 Hashing 37 => 151 Hashing 38 => 152 Hashing 39 => 153 Hashing 40 => 154 Hashing 41 => 155 Hashing 42 => 156 Hashing 43 => 157 Hashing 44 => 158 Hashing 45 => 150 Hashing 46 => 151 Hashing 47 => 152 Hashing 48 => 153 Hashing 49 => 154 Hashing 50 => 155 Hashing 51 => 156 Hashing 52 => 157 Hashing 53 => 158 Hashing 54 => 150 Hashing 55 => 151 Hashing 56 => 152 Hashing 57 => 153 Hashing 58 => 154 Hashing 59 => 155 Hashing 60 => 156 Hashing 61 => 157 Hashing 62 => 158 Hashing 63 => 150 Hashing 64 => 151 Hashing 65 => 152 Hashing 66 => 153 Hashing 67 => 154 Hashing 68 => 155 Hashing 69 => 156 Hashing 70 => 157 Hashing 71 => 158 Hashing 72 => 150 Hashing 73 => 151 Hashing 74 => 152 Hashing 75 => 153 Hashing 76 => 154 Hashing 77 => 155 Hashing 78 => 156 Hashing 79 => 157 Hashing 80 => 158 Hashing 81 => 150 Hashing 82 => 151 Hashing 83 => 152 Hashing 84 => 153 Hashing 85 => 154 Hashing 86 => 155 Hashing 87 => 156 Hashing 88 => 157 Hashing 89 => 158 Hashing 90 => 150 Hashing 91 => 151 Hashing 92 => 152 Hashing 93 => 153 Hashing 94 => 154 Hashing 95 => 155 Hashing 96 => 156 Hashing 97 => 157 Hashing 98 => 158 Hashing 99 => 150 Hashing 100 => 154 Hashing 101 => 155 Hashing 102 => 156 Hashing 103 => 157 Hashing 104 => 158 Hashing 105 => 150 Hashing 106 => 151 Hashing 107 => 152 Hashing 108 => 153 Hashing 109 => 154 Hashing 110 => 155 Hashing 111 => 156 Hashing 112 => 157 Hashing 113 => 158 Hashing 114 => 150 Hashing 115 => 151 Hashing 116 => 152 Hashing 117 => 153 Hashing 118 => 154 Hashing 119 => 155 Hashing 120 => 156 Hashing 121 => 157 Hashing 122 => 158 Hashing 123 => 150 Hashing 124 => 151 Hashing 125 => 152 Hashing 126 => 153 Hashing 127 => 154 Hashing 128 => 155 Hashing 129 => 156 Hashing 130 => 157 Hashing 131 => 158 Hashing 132 => 150 Hashing 133 => 151 Hashing 134 => 152 Hashing 135 => 153 Hashing 136 => 154 Hashing 137 => 155 Hashing 138 => 156 Hashing 139 => 157 Hashing 140 => 158 Hashing 141 => 150 Hashing 142 => 151 Hashing 143 => 152 Hashing 144 => 153 Hashing 145 => 154 Hashing 146 => 155 Hashing 147 => 156 Hashing 148 => 157 Hashing 149 => 158 Hashing 150 => 150 Hashing 151 => 151 Hashing 152 => 152 Hashing 153 => 153 Hashing 154 => 154 Hashing 155 => 155 Hashing 156 => 156 Hashing 157 => 157 Hashing 158 => 158 Hashing 159 => 159 Hashing 160 => 151 Hashing 161 => 152 Hashing 162 => 153 Hashing 163 => 154 Hashing 164 => 155 Hashing 165 => 156 Hashing 166 => 157 Hashing 167 => 158 Hashing 168 => 159 Hashing 169 => 151 Hashing 170 => 152 Hashing 171 => 153 Hashing 172 => 154 Hashing 173 => 155 Hashing 174 => 156 Hashing 175 => 157 Hashing 176 => 158 Hashing 177 => 159 Hashing 178 => 151 Hashing 179 => 152 Hashing 180 => 153 Hashing 181 => 154 Hashing 182 => 155 Hashing 183 => 156 Hashing 184 => 157 Hashing 185 => 158 Hashing 186 => 159 Hashing 187 => 151 Hashing 188 => 152 Hashing 189 => 153 Hashing 190 => 154 Hashing 191 => 155 Hashing 192 => 156 Hashing 193 => 157 Hashing 194 => 158 Hashing 195 => 159 Hashing 196 => 151 Hashing 197 => 152 Hashing 198 => 153 Hashing 199 => 154 Hashing 200 => 155 Hashing 201 => 156 Hashing 202 => 157 Hashing 203 => 158 Hashing 204 => 150 Hashing 205 => 151 Hashing 206 => 152 Hashing 207 => 153 Hashing 208 => 154 Hashing 209 => 155 Hashing 210 => 156 Hashing 211 => 157 Hashing 212 => 158 Hashing 213 => 150 Hashing 214 => 151 Hashing 215 => 152 Hashing 216 => 153 Hashing 217 => 154 Hashing 218 => 155 Hashing 219 => 156 Hashing 220 => 157 Hashing 221 => 158 Hashing 222 => 150 Hashing 223 => 151 Hashing 224 => 152 Hashing 225 => 153 Hashing 226 => 154 Hashing 227 => 155 Hashing 228 => 156 Hashing 229 => 157 Hashing 230 => 158 Hashing 231 => 150 Hashing 232 => 151 Hashing 233 => 152 Hashing 234 => 153 Hashing 235 => 154 Hashing 236 => 155 Hashing 237 => 156 Hashing 238 => 157 Hashing 239 => 158 Hashing 240 => 150 Hashing 241 => 151 Hashing 242 => 152 Hashing 243 => 153 Hashing 244 => 154 Hashing 245 => 155 Hashing 246 => 156 Hashing 247 => 157 Hashing 248 => 158 Hashing 249 => 159 Hashing 250 => 151 Hashing 251 => 152 Hashing 252 => 153 Hashing 253 => 154 Hashing 254 => 155 Hashing 255 => 156 

हमने खुद को 8 मानों तक सीमित कर लिया है … यह बुरा है … हमारे मूल समारोह S(∞) S(256) पर मैप किए गए हैं। यही है कि हमने एक आउटजेप फंक्शन मेपिंग $input को बनाया है।

चूंकि हमारे पास एक सर्जेटिव फ़ंक्शन है, इसलिए हमारे पास कोई गारंटी नहीं है कि इनपुट के किसी भी उपसेट के मैपिंग में टकराव नहीं होंगे (वास्तव में, वे व्यवहार में करेंगे)।

यह वही हुआ जो यहाँ हुआ! हमारा फ़ंक्शन खराब था, लेकिन ऐसा इसलिए नहीं है कि यह काम (यही कारण है कि यह इतनी जल्दी और इतनी पूरी तरह से काम किया)।

MD5 साथ ऐसा ही होता है। यह S(∞) पर S(∞) S(2^128) नक्शे चूंकि इसमें कोई गारंटी नहीं है कि MD5(S(output)) चलने MD5(S(output)) इंजेक्शन होगा, जिसका अर्थ है कि यह टकराव नहीं होगा।

टीएल / डीआर अनुभाग

इसलिए, आउटपुट को सीधे md5 खिला देने से सीधे टकराव उत्पन्न हो सकते हैं, हर चलने से टकराव की संभावना बढ़ जाएगी। हालांकि यह एक रैखिक वृद्धि है, जिसका अर्थ है कि 2^128 का परिणाम सेट कम हो जाता है, लेकिन यह एक महत्वपूर्ण दोष होने के लिए काफी तेजी से कम नहीं है।

इसलिए,

 $output = md5($input); // 2^128 possibilities $output = md5($output); // < 2^128 possibilities $output = md5($output); // < 2^128 possibilities $output = md5($output); // < 2^128 possibilities $output = md5($output); // < 2^128 possibilities 

जितनी बार आप पुनरावृत्त करेंगे, उतना ही कमी होगी।

जोड़

सौभाग्य से हमारे लिए, इसे ठीक करने का एक तुच्छ तरीका है: कुछ और पुनरावृत्तियों में वापस फ़ीड करें:

 $output = md5($input); // 2^128 possibilities $output = md5($input . $output); // 2^128 possibilities $output = md5($input . $output); // 2^128 possibilities $output = md5($input . $output); // 2^128 possibilities $output = md5($input . $output); // 2^128 possibilities 

ध्यान दें कि $input प्रत्येक व्यक्ति के मूल्य के लिए आगे दोहराव 2 ^ 128 नहीं है। जिसका मतलब है कि हम $input मूल्य उत्पन्न करने में सक्षम हो सकते हैं जो अभी भी लाइन को टकराने (और इसलिए 2^128 संभावित आउटपुट से कम से कम पर निर्भर करेगा या अनुनाद करेंगे) लेकिन $input का सामान्य मामला अब भी उतना ही मजबूत है क्योंकि यह एक दौर के लिए था

रुको, क्या यह था? आइए इसे हमारे हमारे ourHash() फ़ंक्शन के साथ परीक्षण करें। $hash = ourHash($input . $hash); स्विच करना $hash = ourHash($input . $hash); , 100 पुनरावृत्तियों के लिए:

 Hashing 0 => 201 Hashing 1 => 212 Hashing 2 => 199 Hashing 3 => 201 Hashing 4 => 203 Hashing 5 => 205 Hashing 6 => 207 Hashing 7 => 209 Hashing 8 => 211 Hashing 9 => 204 Hashing 10 => 251 Hashing 11 => 147 Hashing 12 => 251 Hashing 13 => 148 Hashing 14 => 253 Hashing 15 => 0 Hashing 16 => 1 Hashing 17 => 2 Hashing 18 => 161 Hashing 19 => 163 Hashing 20 => 147 Hashing 21 => 251 Hashing 22 => 148 Hashing 23 => 253 Hashing 24 => 0 Hashing 25 => 1 Hashing 26 => 2 Hashing 27 => 161 Hashing 28 => 163 Hashing 29 => 8 Hashing 30 => 251 Hashing 31 => 148 Hashing 32 => 253 Hashing 33 => 0 Hashing 34 => 1 Hashing 35 => 2 Hashing 36 => 161 Hashing 37 => 163 Hashing 38 => 8 Hashing 39 => 4 Hashing 40 => 148 Hashing 41 => 253 Hashing 42 => 0 Hashing 43 => 1 Hashing 44 => 2 Hashing 45 => 161 Hashing 46 => 163 Hashing 47 => 8 Hashing 48 => 4 Hashing 49 => 9 Hashing 50 => 253 Hashing 51 => 0 Hashing 52 => 1 Hashing 53 => 2 Hashing 54 => 161 Hashing 55 => 163 Hashing 56 => 8 Hashing 57 => 4 Hashing 58 => 9 Hashing 59 => 11 Hashing 60 => 0 Hashing 61 => 1 Hashing 62 => 2 Hashing 63 => 161 Hashing 64 => 163 Hashing 65 => 8 Hashing 66 => 4 Hashing 67 => 9 Hashing 68 => 11 Hashing 69 => 4 Hashing 70 => 1 Hashing 71 => 2 Hashing 72 => 161 Hashing 73 => 163 Hashing 74 => 8 Hashing 75 => 4 Hashing 76 => 9 Hashing 77 => 11 Hashing 78 => 4 Hashing 79 => 3 Hashing 80 => 2 Hashing 81 => 161 Hashing 82 => 163 Hashing 83 => 8 Hashing 84 => 4 Hashing 85 => 9 Hashing 86 => 11 Hashing 87 => 4 Hashing 88 => 3 Hashing 89 => 17 Hashing 90 => 161 Hashing 91 => 163 Hashing 92 => 8 Hashing 93 => 4 Hashing 94 => 9 Hashing 95 => 11 Hashing 96 => 4 Hashing 97 => 3 Hashing 98 => 17 Hashing 99 => 13 Hashing 100 => 246 Hashing 101 => 248 Hashing 102 => 49 Hashing 103 => 44 Hashing 104 => 255 Hashing 105 => 198 Hashing 106 => 43 Hashing 107 => 51 Hashing 108 => 202 Hashing 109 => 2 Hashing 110 => 248 Hashing 111 => 49 Hashing 112 => 44 Hashing 113 => 255 Hashing 114 => 198 Hashing 115 => 43 Hashing 116 => 51 Hashing 117 => 202 Hashing 118 => 2 Hashing 119 => 51 Hashing 120 => 49 Hashing 121 => 44 Hashing 122 => 255 Hashing 123 => 198 Hashing 124 => 43 Hashing 125 => 51 Hashing 126 => 202 Hashing 127 => 2 Hashing 128 => 51 Hashing 129 => 53 Hashing 130 => 44 Hashing 131 => 255 Hashing 132 => 198 Hashing 133 => 43 Hashing 134 => 51 Hashing 135 => 202 Hashing 136 => 2 Hashing 137 => 51 Hashing 138 => 53 Hashing 139 => 55 Hashing 140 => 255 Hashing 141 => 198 Hashing 142 => 43 Hashing 143 => 51 Hashing 144 => 202 Hashing 145 => 2 Hashing 146 => 51 Hashing 147 => 53 Hashing 148 => 55 Hashing 149 => 58 Hashing 150 => 198 Hashing 151 => 43 Hashing 152 => 51 Hashing 153 => 202 Hashing 154 => 2 Hashing 155 => 51 Hashing 156 => 53 Hashing 157 => 55 Hashing 158 => 58 Hashing 159 => 0 Hashing 160 => 43 Hashing 161 => 51 Hashing 162 => 202 Hashing 163 => 2 Hashing 164 => 51 Hashing 165 => 53 Hashing 166 => 55 Hashing 167 => 58 Hashing 168 => 0 Hashing 169 => 209 Hashing 170 => 51 Hashing 171 => 202 Hashing 172 => 2 Hashing 173 => 51 Hashing 174 => 53 Hashing 175 => 55 Hashing 176 => 58 Hashing 177 => 0 Hashing 178 => 209 Hashing 179 => 216 Hashing 180 => 202 Hashing 181 => 2 Hashing 182 => 51 Hashing 183 => 53 Hashing 184 => 55 Hashing 185 => 58 Hashing 186 => 0 Hashing 187 => 209 Hashing 188 => 216 Hashing 189 => 219 Hashing 190 => 2 Hashing 191 => 51 Hashing 192 => 53 Hashing 193 => 55 Hashing 194 => 58 Hashing 195 => 0 Hashing 196 => 209 Hashing 197 => 216 Hashing 198 => 219 Hashing 199 => 220 Hashing 200 => 248 Hashing 201 => 49 Hashing 202 => 44 Hashing 203 => 255 Hashing 204 => 198 Hashing 205 => 43 Hashing 206 => 51 Hashing 207 => 202 Hashing 208 => 2 Hashing 209 => 51 Hashing 210 => 49 Hashing 211 => 44 Hashing 212 => 255 Hashing 213 => 198 Hashing 214 => 43 Hashing 215 => 51 Hashing 216 => 202 Hashing 217 => 2 Hashing 218 => 51 Hashing 219 => 53 Hashing 220 => 44 Hashing 221 => 255 Hashing 222 => 198 Hashing 223 => 43 Hashing 224 => 51 Hashing 225 => 202 Hashing 226 => 2 Hashing 227 => 51 Hashing 228 => 53 Hashing 229 => 55 Hashing 230 => 255 Hashing 231 => 198 Hashing 232 => 43 Hashing 233 => 51 Hashing 234 => 202 Hashing 235 => 2 Hashing 236 => 51 Hashing 237 => 53 Hashing 238 => 55 Hashing 239 => 58 Hashing 240 => 198 Hashing 241 => 43 Hashing 242 => 51 Hashing 243 => 202 Hashing 244 => 2 Hashing 245 => 51 Hashing 246 => 53 Hashing 247 => 55 Hashing 248 => 58 Hashing 249 => 0 Hashing 250 => 43 Hashing 251 => 51 Hashing 252 => 202 Hashing 253 => 2 Hashing 254 => 51 Hashing 255 => 53 

वहाँ अभी भी एक मोटा पैटर्न है, लेकिन ध्यान दें कि यह हमारे अंतर्निहित कार्य (जो पहले से काफी कमजोर था) की तुलना में एक पैटर्न का अधिक नहीं है।

हालांकि नोटिस कि 0 और 3 टकराव हो गए, हालांकि वे एकल रन में नहीं थे। यह मैंने पहले कहा था कि क्या एक आवेदन है (टक्कर प्रतिरोध सभी निविष्टियों के सेट के लिए ही रहता है, लेकिन अंतर्निहित एल्गोरिदम में खामियों के कारण विशिष्ट टक्कर मार्ग खुले हो सकते हैं)

टीएल / डीआर अनुभाग

प्रत्येक पुनरावृत्ति में इनपुट को वापस खिलाकर, हम प्रभावी रूप से किसी भी टकराव को तोड़ते हैं जो पूर्व आवृत्ति में हो सकते हैं।

इसलिए, md5($input . md5($input)); ( सैद्धांतिक रूप से कम से कम) md5($input) रूप में मजबूत होना चाहिए।

क्या यह महत्वपूर्ण है?

हाँ। यह कारणों में से एक है कि पीबीकेडीएफ 2 ने आरएफसी 28 9 8 में पीबीकेडीएफ 1 की जगह ली। दोनों के आंतरिक छोरों पर विचार करें ::

PBKDF1:

 T_1 = Hash (P || S) , T_2 = Hash (T_1) , ... T_c = Hash (T_{c-1}) 

जहां c चलना गणना है, P पासवर्ड है और S नमक है

PBKDF2:

 U_1 = PRF (P, S || INT (i)) , U_2 = PRF (P, U_1) , ... U_c = PRF (P, U_{c-1}) 

जहां पीआरएफ वास्तव में सिर्फ एक एचएमएसी है लेकिन यहां हमारे प्रयोजनों के लिए, चलिए बस PRF(P, S) = Hash(P || S) (यानी, दो निविष्टियों का पीआरएफ एक जैसा है, मोटे तौर पर बोल रहा है, जैसा कि दोनों को एक साथ संमिलित किया गया है) यह बहुत अधिक नहीं है , लेकिन हमारे उद्देश्य के लिए यह है।

तो पीबीकेडीएफ 2 अंतर्निहित Hash फ़ंक्शन के टकराव प्रतिरोध को बनाए रखता है, जहां पीबीकेडीएफ 1 नहीं करता है।

यह सब एक साथ टाई-

हम एक हैश चलने के सुरक्षित तरीके के बारे में जानते हैं। असल में:

 $hash = $input; $i = 10000; do { $hash = hash($input . $hash); } while ($i-- > 0); 

आम तौर पर सुरक्षित है

अब, हम क्यों इसे हश्म करना चाहते हैं में जाने के लिए, चलो entropy आंदोलन का विश्लेषण करते हैं

एक हैश अनंत सेट में लेता है: S(∞) और एक छोटे, लगातार आकार सेट S(n) उत्पादन करता है। अगला पुनरावृत्ति (इनपुट को संभालने में वापस पारित किया गया है) S(∞) S(n) दोबारा आइए:

 S(∞) -> S(n) S(∞) -> S(n) S(∞) -> S(n) S(∞) -> S(n) S(∞) -> S(n) S(∞) -> S(n) 

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

हालांकि फिर से चलने के लिए लाभ है यह हैशिंग प्रक्रिया कृत्रिम रूप से धीमी है। और यही कारण है कि चलना एक अच्छा विचार हो सकता है। वास्तव में, यह सबसे आधुनिक पासवर्ड हैशिंग एल्गोरिदम का मूल सिद्धांत है (तथ्य यह है कि कुछ अधिक करना और धीमा बनाता है)।

धीमा अच्छा है, क्योंकि यह प्राथमिक सुरक्षा खतरे का सामना कर रहा है: जबरदस्ती मजबूर धीमा हम अपने हैशिंग एल्गोरिथ्म बनाते हैं, कठिन हमलावरों को हमारे द्वारा चुरे हुए पासवर्ड हैशों पर हमला करने के लिए काम करना होगा। और यह एक अच्छी बात है !!!

हां, पुनः हैशिंग खोज की जगह कम कर देता है, लेकिन नहीं, यह कोई फर्क नहीं पड़ता – प्रभावी कमी नगण्य है

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

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

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

हां – यह स्ट्रिंग से मेल खाने वाले संभावित स्ट्रिंग्स की संख्या कम कर देता है।

जैसा कि आपने पहले ही उल्लेख किया है, नमकीन हैश बहुत बेहतर है।

यहां एक लेख: http://websecurity.ro/blog/2007/11/02/md5md5-vs-md5/ , यह समरूप क्यों है, इस पर एक प्रमाण का प्रयास करता है, लेकिन मुझे तर्क के बारे में निश्चित नहीं है। आंशिक रूप से वे मानते हैं कि एमडी 5 (एमडी 5 (टेक्स्ट)) का विश्लेषण करने के लिए सॉफ्टवेयर उपलब्ध नहीं है, लेकिन जाहिर है इंद्रधनुष तालिकाओं का उत्पादन करने के लिए यह काफी तुच्छ है।

I'm still sticking with my answer that there are smaller number of md5(md5(text)) type hashes than md5(text) hashes, increasing the chance of collision (even if still to an unlikely probability) and reducing the search space.

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); 

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.

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).

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.

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 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.

So in short:

  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.

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.

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.

हाँ।

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.

I'm going to go out on a limb and say it's more secure in certain circumstances… don't downvote me yet though!

From a mathematical / cryptographical point of view, it's less secure, for reasons that I'm sure someone else will give you a clearer explanation of than I could.

However , there exist large databases of MD5 hashes, which are more likely to contain the "password" text than the MD5 of it. So by double-hashing you're reducing the effectiveness of those databases.

Of course, if you use a salt then this advantage (disadvantage?) goes away.