डेटाबेस में Bcrypt हैशेड पासवर्ड को संग्रहीत करने के लिए मुझे किस प्रकार का कॉलम / लंबाई का उपयोग करना चाहिए?


317

मैं एक डेटाबेस में हैशेड पासवर्ड (बीसीक्रिप्ट का उपयोग करके) स्टोर करना चाहता हूं। इसके लिए एक अच्छा प्रकार क्या होगा, और कौन सी सही लंबाई होगी? क्या पासवर्ड एक ही लंबाई के बीसीक्रिप्ट के साथ हैशेड हैं?

संपादित करें

उदाहरण हैश:

$2a$10$KssILxWNR6k62B7yiX0GAe2Q7wwHlrzhF3LqtVvpyvHZf0MwvNfVu

कुछ पासवर्ड हैशिंग के बाद, ऐसा लगता है कि बीसीक्रिप्ट हमेशा 60 चरित्र हैश उत्पन्न करता है।

EDIT 2

कार्यान्वयन का उल्लेख नहीं करने के लिए क्षमा करें। मैं jBCrypt का उपयोग कर रहा हूं


ओपनवॉल का PHP पासवर्ड हैशिंग ढाँचा (PHPass) भी देखें। उपयोगकर्ता पासवर्ड पर कई आम हमलों के खिलाफ इसकी पोर्टेबल और कठोर। जिस व्यक्ति ने फ्रेमवर्क (सोलरडिजाइनर) लिखा है, वह वही व्यक्ति है जिसने जॉन द रिपर लिखा था और पासवर्ड हैशिंग प्रतियोगिता में एक न्यायाधीश के रूप में बैठता है । इसलिए वह पासवर्ड पर हमलों के बारे में एक या दो चीजें जानता है।
jww

1
अगर कोई भी इस खोज पर गिर जाता है, तो यह है कि स्क्रू के लिए एक समाधान : गुमबो का जवाब भी स्थानांतरण के लिए लागू होता है। मैंने व्यक्तिगत रूप से MySQL में BINARY (64) लागू किया और इसने मुझे बाद में पायथन के तहत बाइट समानता के लिए परीक्षण करने की अनुमति दी।
फिलिप हेबर्ट

जवाबों:


368

Bcrypt के लिए मॉड्यूलर क्रिप्ट प्रारूप के होते हैं

  • $2$, $2a$या हैशिंग एल्गोरिथ्म और प्रारूप की$2y$ पहचान करना
  • एक दो अंकों का मूल्य लागत पैरामीटर को दर्शाते हुए, उसके बाद $
  • एक 53 वर्ण लंबा आधार -64 एन्कोडेड मूल्य (वे वर्णमाला का उपयोग ., /, 0- 9, A- Z, a- zकि करने के लिए अलग है मानक बेस 64 एन्कोडिंग वर्णमाला) से मिलकर:
    • नमक के 22 अक्षर (प्रभावी रूप से 132 डिकोड बिट्स के केवल 128 बिट्स)
    • एन्क्रिप्टेड आउटपुट के 31 वर्ण (प्रभावी रूप से 186 डिकोड बिट्स में से केवल 184 बिट्स)

इस प्रकार कुल लंबाई क्रमशः 59 या 60 बाइट्स है।

जैसा कि आप 2a प्रारूप का उपयोग करते हैं, आपको 60 बाइट की आवश्यकता होगी। और MySQL के लिए इस प्रकार मैं उपयोग करने के लिए सुझाव देंगे CHAR(60) BINARYयाBINARY(60) (देखें _bin और बाइनरी collations अंतर के बारे में जानकारी के लिए)।

CHARद्विआधारी सुरक्षित नहीं है और समानता केवल बाइट मूल्य पर निर्भर नहीं होती है, लेकिन वास्तविक टकराव पर; सबसे खराब स्थिति Aमें इसके बराबर माना जाता है a। देखें और collations अधिक जानकारी के लिए।_binbinary


28
जागरूक रहें - बाइनरी (60) के रूप में भंडारण स्ट्रिंग समानता (अन्य चीजों के बीच) के लिए अप्रत्याशित व्यवहार का कारण बन सकता है। .NET में इसे String.Equals (fromDataBaseBinary60string, TypishString, StringComparison.InvariantCulture)
JHubbard80

8
यदि आप कॉलम को CHAR (60) CHARACTER SET latin1 COLLATE latin1_bin के रूप में परिभाषित करते हैं, तो अब आपको बाइनरी कॉलम की आवश्यकता के बिना सटीक स्ट्रिंग तुलना के फायदे मिलते हैं।
बेन

2
@AndreFigueiredo SQL_Latin1_General_CP1_CS_ASMySQL में अज्ञात है। जो जाना जाता है latin1_general_cs
गुमबो

1
मैं यहाँ के लिए एक परिभाषा की प्यार होता क्या 2, 2aहै, और 2yहैशिंग एल्गोरिथ्म और प्रारूप के लिए मतलब। मैं कुछ खोज के साथ एक आसान जवाब नहीं दे सकता।
13

2
@ समस्या यह है कि आप अलग-अलग हैश के बराबर होने की तुलना कर सकते हैं। यदि आप स्पष्ट रूप से निर्दिष्ट करते हैं कि यह एक द्विआधारी स्तंभ है (या सही टकराव के साथ VARCHAR), तो आप कहीं और, कुछ सेटिंग को बदलने के जोखिम को नहीं चलाते हैं जो इसे एक मामले में असंवेदनशील तुलना बनाता है। यह आपके इरादे को और भी स्पष्ट करता है, जो आम तौर पर एक अच्छी बात है - आप बाइनरी डेटा स्टोर कर रहे हैं; आपको इसे बाइनरी डेटा के रूप में संग्रहीत करना चाहिए।
निधि मोनिका का मुकदमा

51

एक Bcrypt हैश को एक BINARY(40)कॉलम में संग्रहीत किया जा सकता है ।

BINARY(60), जैसा कि अन्य उत्तर बताते हैं, सबसे आसान और सबसे स्वाभाविक विकल्प है, लेकिन अगर आप भंडारण क्षमता को अधिकतम करना चाहते हैं, तो आप 20 बाइट्स को हानिरहित डिकंस्ट्रक्ट करके बचा सकते हैं। मैंने GitHub पर इसे और अच्छी तरह से प्रलेखित किया है: https://github.com/ademarre/binary-mcf

Bcrypt हैश मॉड्यूलर संरचना क्रिप्ट प्रारूप (MCF) के रूप में संदर्भित एक संरचना का पालन करें। बाइनरी MCF (BMCF) एक अधिक कॉम्पैक्ट बाइनरी संरचना के लिए इन पाठीय हैश अभ्यावेदन को डिकोड करता है। Bcrypt के मामले में, परिणामी बाइनरी हैश 40 बाइट्स है।

Gumbo ने Bcrypt MCF हैश के चार घटकों को समझाने का अच्छा काम किया:

$<id>$<cost>$<salt><digest>

BMCF को डिकोड करना इस तरह से है:

  1. $<id>$ 3 बिट्स में प्रतिनिधित्व किया जा सकता है।
  2. <cost>$, 04-31, 5 बिट्स में प्रतिनिधित्व किया जा सकता है। 1 बाइट के लिए इन्हें एक साथ रखें।
  3. 22-वर्ण नमक 128 बिट्स का एक (गैर-मानक) आधार -64 प्रतिनिधित्व है। बेस -64 डिकोडिंग से 16 बाइट मिलती हैं।
  4. 31-कैरेक्टर हैश डाइजेस्ट बेस -64 को 23 बाइट्स में डिकोड किया जा सकता है।
  5. इसे 40 बाइट्स के लिए एक साथ रखें: 1 + 16 + 23

आप ऊपर दिए गए लिंक पर अधिक पढ़ सकते हैं, या मेरे PHP कार्यान्वयन की जांच कर सकते हैं , GitHub पर भी।


49
लंबे समय तक क्षेत्र की लागत: 20 बाइट्स एक मिलियन + रिकॉर्ड: 20 एमबी, एक बार जब आप एक लाख रिकॉर्ड तक पहुंचते हैं। एक अत्यधिक जटिल सुरक्षा और इंजीनियरिंग क्षेत्र में अनुचित रूप से लंबाई की लंबाई को लागू करने की लागत: $ $ $ $ $ $ $ $ $ $ $ $ $ $। $ $ $ $ $ $ $ $ $ $ $ आप गणित करते हैं।
काजकाई

6
@Kzqai, जैसा कि मैंने कहा, बड़ा 60-बाइट कॉलम सबसे प्राकृतिक विकल्प है, लेकिन भंडारण क्षमता को आगे बढ़ाने के लिए आक्रामक रूप से परियोजना निर्भर है। उदाहरण के लिए, पूरे डेटाबेस को स्मृति में फिट करने की कोशिश करना आम है, और यहां 20 एमबी और एक अन्य 20 मेमोरी-विवश वातावरण में जल्दी से जोड़ सकते हैं।
आंद्रे डी

10
आपका उदाहरण मेरी बात में है। --- यदि आप अपने डेटाबेस को मेमोरी में रखना चाहते हैं, तो bcrypt storage कॉलम को छूने से पहले हर दूसरे कॉलम को ऑप्टिमाइज़ करें। --- यदि आपने पागल डिग्री के लिए हर दूसरे कॉलम को अनुकूलित किया है, और केवल bcrypt हैश कॉलम बचा है, तो बस bcrypt के लिए मेमोरी का एक और टमटम प्राप्त करें। --- यदि आपने उपरोक्त दोनों काम किए हैं, तो ... बंद करो, आपने कम लटके फल के हर दूसरे कॉलम को अनुकूलित नहीं किया है, और आप परीक्षण किए गए क्रिप्टोग्राफ़िक सुरक्षा प्रणाली के साथ गड़बड़ करने वाले हैं और काम करते हैं कार्यान्वयन विफलता की संभावना के साथ यह अधिक जटिल घर में विकसित प्रणाली के साथ है।
Kzqai

11
@Kzqai यहां आपके Bcrypt पुस्तकालय की सुरक्षा को कमजोर करने का कोई जोखिम नहीं है। यह एक डेटा एन्कोडिंग है जो पासवर्ड की जांच से पहले भंडारण से पुनर्प्राप्ति पर पूर्ववत हो जाता है। यह "अपने स्वयं के क्रिप्टो क्षेत्र को रोल न करें" नहीं है।
आंद्रे डी

1
अच्छी व्याख्या। :) यद्यपि आपके स्पष्टीकरण ने एक महान विचार दिया, मैं सिर्फ 60 वर्णों, यहां तक ​​कि 100 वर्णों के साथ जाना चाहता हूं, बस सुरक्षित पक्ष पर होना चाहिए। अच्छी बहस भी @Kzqai और आंद्रेडी
नवीन कुमार V

23

यदि आप bcrypt हैश उत्पन्न करने के password_hash()लिए PASSWORD_DEFAULTएल्गोरिथ्म के साथ PHP का उपयोग कर रहे हैं (जो मुझे लगता है कि यह प्रश्न पढ़ने वाले लोगों का एक बड़ा प्रतिशत है) तो यह ध्यान रखना सुनिश्चित करें कि भविष्य password_hash()में डिफ़ॉल्ट के रूप में एक अलग एल्गोरिथ्म का उपयोग कर सकता है और इसलिए ऐसा हो सकता है। हैश की लंबाई को प्रभावित करें (लेकिन यह जरूरी नहीं कि अधिक लंबा हो)।

मैनुअल पेज से:

ध्यान दें कि यह स्थिरांक समय के साथ बदलने के लिए डिज़ाइन किया गया है क्योंकि PHP में नए और मजबूत एल्गोरिदम जोड़े जाते हैं। उस कारण से, इस पहचानकर्ता के उपयोग से परिणाम की लंबाई समय के साथ बदल सकती है। इसलिए, परिणाम को एक डेटाबेस कॉलम में संग्रहीत करने की सिफारिश की जाती है जो 60 वर्णों से आगे बढ़ सकता है (255 वर्ण एक अच्छा विकल्प होगा)।

यदि आप 1 बिलियन यूजर्स के साथ 1 बिलियन यूजर्स हैं (यानी आप इस समय facebook से प्रतिस्पर्धा कर रहे हैं) bcrypt का उपयोग करते हुए, यह एक छोटे से SSD हार्ड ड्राइव के आकार के बारे में केवल ~ 255 GB डेटा - होगा। यह बहुत कम संभावना नहीं है कि पासवर्ड हैश को संग्रहीत करने से आपके आवेदन में अड़चन होने वाली है। हालाँकि इस बात की संभावना नहीं है कि स्टोरेज स्पेस वास्तव में किसी कारण से एक समस्या है, आप bcrypt का उपयोग PASSWORD_BCRYPTकरने के लिए बाध्य कर सकते हैं password_hash(), भले ही वह डिफ़ॉल्ट न हो। बस जब भी कोई नया PHP संस्करण रिलीज़ होता है, तो bcrypt में पाई गई किसी भी भेद्यता के बारे में सूचित रहना और रिलीज़ नोट्स की समीक्षा करना सुनिश्चित करें। यदि डिफ़ॉल्ट एल्गोरिदम को कभी भी बदल दिया जाता है तो यह समीक्षा करना अच्छा होगा कि नया एल्गोरिदम का उपयोग क्यों किया जाए या नहीं एक सूचित निर्णय लिया जाए।


20

मुझे नहीं लगता कि कोई भी साफ-सुथरी तरकीब है जिसे आप स्टोर कर सकते हैं जैसे कि आप एमडी 5 हैश के साथ कर सकते हैं।

मुझे लगता है कि आपका सबसे अच्छा दांव इसे स्टोर करना है CHAR(60)क्योंकि यह हमेशा 60 चार्ट लंबा होता है


हालांकि, PHP प्रलेखन नोट करता है कि कॉलम भविष्य के रिलीज के लिए अधिक डेटा रखने में सक्षम होना चाहिए ...
जूलियन एफ। वेनर्ट

16
सोने की थाली का कोई कारण नहीं। यदि आप जिस सॉफ़्टवेयर का उपयोग कर रहे हैं, उसके लिए साठ बाइट्स की आवश्यकता होती है, तो साठ बाइट्स आवंटित करें। यदि आपके सॉफ़्टवेयर में भविष्य में रिलीज़ होता है जो इसे बदलता है, तो आप इसके बारे में चिंता कर सकते हैं कि जब यह रिलीज़ होगा। आपको स्वचालित रूप से कार्यक्षमता-परिवर्तन अपडेट स्थापित नहीं करना चाहिए।
टायलर क्रॉम्पटन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.