php Blowfish के साथ हैश लंबे पासवर्ड(> 72 वर्ण) कैसे है




security hash (3)

यहां समस्या मूल रूप से एन्ट्रॉपी की समस्या है। तो आइए वहां देखना शुरू करें:

प्रति चरित्र एंट्रॉपी

एंटोपी प्रति बाइट की बिट्स की संख्या हैं:

  • हेक्स वर्ण
    • बिट्स: 4
    • मान: 16
    • 72 वर्णों में एंट्रॉपी: 288 बिट्स
  • अल्फा-न्यूमेरिक
    • बिट्स: 6
    • मूल्य: 62
    • 72 वर्णों में प्रवेश: 432 बिट्स
  • "आम" प्रतीक
    • बिट्स: 6.5
    • मूल्य: 94
    • 72 वर्णों में प्रवेश: 468 बिट्स
  • पूर्ण बाइट्स
    • बिट्स: 8
    • मूल्य: 255
    • 72 वर्णों में एंट्रॉपी: 576 बिट्स

तो, हम कैसे कार्य करते हैं इस बात पर निर्भर करता है कि हम किस प्रकार के पात्रों की अपेक्षा करते हैं।

पहली समस्या

आपके कोड के साथ पहली समस्या यह है कि आपका "काली मिर्च" हैश चरण हेक्स वर्णों को hash_hmac() के चौथे पैरामीटर को सेट नहीं किया गया है)।

इसलिए, अपने काली मिर्च को हराकर, आप प्रभावी रूप से 2 के कारक (576 से 288 संभव बिट्स) द्वारा पासवर्ड पर उपलब्ध अधिकतम एन्ट्रॉपी काट रहे हैं।

दूसरी समस्या

हालांकि, sha256 केवल पहले स्थान पर एंट्रॉपी के 256 बिट प्रदान करता है। तो आप प्रभावी रूप से 256 बिट्स तक संभावित 576 बिट्स काट रहे हैं। आपके हैश चरण * तुरंत *, बहुत परिभाषा से पासवर्ड में संभव एंट्रॉपी का कम से कम 50% खो देता है।

आप SHA512 स्विच करके इसे आंशिक रूप से हल कर सकते हैं, जहां आप केवल उपलब्ध एन्ट्रॉपी को लगभग 12% कम कर देंगे। लेकिन यह अभी भी एक महत्वहीन अंतर है। वह 12% 1.8e19 कारक द्वारा क्रमपरिवर्तन की संख्या को कम करता है। यह एक बड़ी संख्या है ... और यही वह कारक है जो इसे कम करता है ...

अंतर्निहित मुद्दा

अंतर्निहित मुद्दा यह है कि 72 वर्णों से तीन प्रकार के पासवर्ड हैं। इस शैली प्रणाली पर उनके प्रभाव का असर बहुत अलग होगा:

नोट: यहां से बाहर मैं मान रहा हूं कि हम एक मिर्च प्रणाली की तुलना कर रहे हैं जो कच्चे आउटपुट (हेक्स नहीं) के साथ SHA512 का उपयोग करता है।

  • उच्च एन्ट्रॉपी यादृच्छिक पासवर्ड

    ये आपके उपयोगकर्ता पासवर्ड जेनरेटर का उपयोग कर रहे हैं जो पासवर्ड के लिए बड़ी चाबियाँ उत्पन्न करते हैं। वे यादृच्छिक हैं (उत्पन्न, मानव चुने नहीं), और प्रति चरित्र उच्च एंट्रॉपी है। ये प्रकार उच्च बाइट्स (वर्ण> 127) और कुछ नियंत्रण वर्णों का उपयोग कर रहे हैं।

    इस समूह के लिए, आपके हैशिंग फ़ंक्शन में उनके उपलब्ध एन्ट्रॉपी को bcrypt में काफी कम कर दिया bcrypt

    मुझे फिर वही बात कहना है। उच्च एन्ट्रॉपी, लंबे पासवर्ड का उपयोग करने वाले उपयोगकर्ताओं के लिए, आपका समाधान मापने योग्य राशि से अपने पासवर्ड की ताकत को कम कर देता है। (72 चरित्र पासवर्ड के लिए एन्ट्रॉपी के 62 बिट्स खो गए, और लंबे पासवर्ड के लिए अधिक)

  • मध्यम एन्ट्रॉपी यादृच्छिक पासवर्ड

    यह समूह सामान्य प्रतीकों वाले पासवर्ड का उपयोग कर रहा है, लेकिन कोई उच्च बाइट या नियंत्रण वर्ण नहीं है। ये आपके विशिष्ट पासवर्ड हैं।

    इस समूह के लिए, आप थोड़ा एन्ट्रॉपी अनलॉक करने जा रहे हैं (इसे न बनाएं, लेकिन अधिक एन्ट्रॉपी को बीक्रिप्ट पासवर्ड में फिट करने दें)। जब मैं थोड़ा कहता हूं, मेरा मतलब थोड़ा सा है। ब्रेक-तब भी होता है जब आप 512 बिट्स को अधिकतम करते हैं जो SHA512 है। इसलिए, चोटी 78 वर्णों पर है।

    मुझे फिर वही बात कहना है। पासवर्ड के इस वर्ग के लिए, आप एंट्रॉपी से बाहर होने से पहले केवल एक अतिरिक्त 6 वर्ण स्टोर कर सकते हैं।

  • कम एन्ट्रॉपी गैर यादृच्छिक पासवर्ड

    यह वह समूह है जो अल्फा-न्यूमेरिक वर्णों का उपयोग कर रहे हैं जो शायद यादृच्छिक रूप से उत्पन्न नहीं होते हैं। एक बाइबल उद्धरण या ऐसा कुछ। इन वाक्यांशों में प्रति चरित्र एंट्रॉपी के लगभग 2.3 बिट्स हैं।

    इस समूह के लिए, आप हैशिंग द्वारा अधिक एन्ट्रॉपी को अनलॉक कर सकते हैं (इसे नहीं बनाते हैं, लेकिन बीसीआरपीटी पासवर्ड इनपुट में फिट करने की अनुमति देते हैं)। एंट्रॉपी से बाहर होने से पहले ब्रेकवेन लगभग 223 वर्ण हैं।

    आइए फिर से कहें। पासवर्ड के इस वर्ग के लिए, प्री-हैशिंग निश्चित रूप से सुरक्षा को काफी बढ़ाता है।

असली दुनिया में वापस

इन प्रकार की एन्ट्रॉपी गणना वास्तविक दुनिया में वास्तव में ज्यादा मायने रखती नहीं है। एंट्रॉपी अनुमान लगाने का क्या मायने रखता है। यही वह प्रभाव है जो हमलावर कर सकते हैं। यही वह है जिसे आप अधिकतम करना चाहते हैं।

हालांकि थोड़ा सा शोध है जो एंट्रॉपी अनुमान लगाने में चला गया है, कुछ ऐसे मुद्दे हैं जिन्हें मैं इंगित करना चाहता हूं।

पंक्ति में 72 सही वर्णों को यादृच्छिक रूप से अनुमान लगाने की संभावना बहुत कम है। इस टकराव की तुलना में आप पावरबॉल लॉटरी 21 बार जीतने की अधिक संभावना रखते हैं ... इस बारे में हम कितने बड़े हैं, इस बारे में बात कर रहे हैं।

लेकिन हम सांख्यिकीय रूप से इस पर ठोकर नहीं खा सकते हैं। वाक्यांशों के मामले में पहले 72 वर्णों का मौका एक यादृच्छिक पासवर्ड के मुकाबले बहुत अधिक है। लेकिन यह अभी भी बहुत कम है (आप प्रति पंक्ति 2.3 बिट्स के आधार पर पावरबॉल लॉटरी जीतने की अधिक संभावना रखते हैं)।

वास्तव में

व्यावहारिक रूप से, यह वास्तव में कोई फर्क नहीं पड़ता। पहले 72 वर्णों का अनुमान लगाने वाले किसी व्यक्ति की संभावना, जहां बाद वाले लोग महत्वपूर्ण अंतर डालते हैं, इतनी कम है कि चिंता करने योग्य नहीं है। क्यूं कर?

खैर, मान लीजिए कि आप एक वाक्यांश ले रहे हैं। यदि व्यक्ति पहले 72 वर्ण सही प्राप्त कर सकता है, तो वे या तो वास्तव में भाग्यशाली (संभावना नहीं) हैं, या यह एक आम वाक्यांश है। यदि यह एक आम वाक्यांश है, तो केवल एक ही चर यह है कि इसे बनाना कितना लंबा है।

चलो एक उदाहरण लेते हैं। आइए बाइबल से उद्धरण लें (सिर्फ इसलिए कि यह लंबे पाठ का एक आम स्रोत है, किसी अन्य कारण से नहीं):

आप अपने पड़ोसी के घर की लालसा नहीं करेंगे। आप अपने पड़ोसी की पत्नी, या उसके दास या नौकरानी, ​​उसके बैल या गधे, या अपने पड़ोसी से संबंधित कुछ भी नहीं चाहते हैं।

यह 180 वर्ण है। 73 वें चरित्र neighbor's में g है। यदि आपने अनुमान लगाया है, तो आप संभवतः nei पर रोक नहीं सकते हैं, लेकिन शेष कविता के साथ जारी रहे हैं (इस तरह से पासवर्ड का उपयोग होने की संभावना है)। इसलिए, आपके "हैश" में ज्यादा वृद्धि नहीं हुई है।

बीटीडब्ल्यू: मैं बिल्कुल एक बाइबल उद्धरण का उपयोग करने की वकालत नहीं कर रहा हूं। वास्तव में, बिल्कुल विपरीत।

निष्कर्ष

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

लेकिन अंत में, इनमें से कोई भी अत्यधिक महत्वपूर्ण नहीं है। जिन संख्याओं के साथ हम काम कर रहे हैं वे बहुत अधिक हैं। एन्ट्रॉपी में अंतर ज्यादा नहीं होने वाला है।

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

बाकी साइट को सुरक्षित करने पर ध्यान केंद्रित करें। और पासवर्ड की ताकत इंगित करने के लिए पंजीकरण पर पासवर्ड बॉक्स में एक पासवर्ड एन्ट्रॉपी मीटर जोड़ें (और इंगित करें कि कोई पासवर्ड खत्म हो गया है या नहीं, उपयोगकर्ता इसे बदलना चाहता है) ...

यह मेरा $ 0.02 कम से कम (या संभवतः $ 0.02 से अधिक तरीका है) ...

एक "गुप्त" काली मिर्च का उपयोग करने के रूप में दूर तक:

Bcrypt में एक हैश फ़ंक्शन को खिलाने में सचमुच कोई शोध नहीं है। इसलिए, यह सबसे अच्छा नहीं है अगर बीपीआरपीटी में "मिर्च" हैश को खिलाने से अज्ञात भेद्यताएं होती हैं (हम जानते हैं कि hash1(hash2($value)) टकराव प्रतिरोध और प्रीमीज हमलों के आसपास महत्वपूर्ण भेद्यता का पर्दाफाश कर सकता है)।

यह ध्यान में रखते हुए कि आप पहले से ही एक गुप्त कुंजी ("काली मिर्च") को संग्रहीत करने पर विचार कर रहे हैं, इसका उपयोग ऐसे तरीके से क्यों न करें जो अच्छी तरह से पढ़ा और समझा जाए? इसे संग्रहीत करने से पहले हैश को एन्क्रिप्ट क्यों नहीं करें?

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

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

नोट: यदि आप ऐसा करना चुनते हैं, तो लाइब्रेरी का उपयोग करें। PHP के लिए, मैं दृढ़ता से ज़ेंड फ्रेमवर्क 2 के Zend\Crypt पैकेज की अनुशंसा करता हूं। यह वास्तव में एकमात्र ऐसा है जिसे मैं समय पर इस वर्तमान बिंदु पर अनुशंसा करता हूं। इसकी दृढ़ता से समीक्षा की गई है, और यह आपके लिए सभी निर्णय लेता है (जो एक बहुत अच्छी बात है) ...

कुछ इस तरह:

use Zend\Crypt\BlockCipher;

public function createHash($password) {
    $hash = password_hash($password, PASSWORD_BCRYPT, ["cost"=>$this->cost]);

    $blockCipher = BlockCipher::factory('mcrypt', array('algo' => 'aes'));
    $blockCipher->setKey($this->key);
    return $blockCipher->encrypt($hash);
}

public function verifyHash($password, $hash) {
    $blockCipher = BlockCipher::factory('mcrypt', array('algo' => 'aes'));
    $blockCipher->setKey($this->key);
    $hash = $blockCipher->decrypt($hash);

    return password_verify($password, $hash);
}

और यह फायदेमंद है क्योंकि आप सभी एल्गोरिदम का उपयोग उन तरीकों से कर रहे हैं जो अच्छी तरह से समझते हैं और अच्छी तरह से अध्ययन किए जाते हैं (अपेक्षाकृत कम से कम)। याद है:

किसी भी, सबसे अनजान शौकिया से सर्वश्रेष्ठ क्रिप्टोग्राफर तक, एक एल्गोरिदम बना सकता है कि वह खुद तोड़ नहीं सकता है।

पिछले हफ्ते मैंने पासवर्ड हैशिंग और ब्लॉफिश के बारे में बहुत सारे लेख पढ़े हैं (अभी में) सबसे अच्छा हैशिंग एल्गोरिदम है - लेकिन यह इस सवाल का विषय नहीं है!

72 वर्ण सीमा

Blowfish केवल दर्ज पासवर्ड में पहले 72 वर्णों पर विचार करें:

<?php
$password = "Wow. This is a super secret and super, super long password. Let's add some special ch4r4ct3rs a#d everything is fine :)";
$hash = password_hash($password, PASSWORD_BCRYPT);
var_dump($password);

$input = substr($password, 0, 72);
var_dump($input);

var_dump(password_verify($input, $hash));
?>

आउटपुट है:

string(119) "Wow. This is a super secret and super, super long password. Let's add some special ch4r4ct3rs a#d everything is fine :)"
string(72) "Wow. This is a super secret and super, super long password. Let's add so"
bool(true)

जैसा कि आप केवल पहले 72 वर्णों को देख सकते हैं। ट्विटर अपने पासवर्ड ( https://shouldichangemypassword.com/twitter-hacked.php ) को स्टोर करने के लिए blowfish उर्फ ​​bcrypt का उपयोग कर रहा है और अनुमान लगाएं: 72 से अधिक वर्णों के साथ अपने ट्विटर पासवर्ड को लंबे पासवर्ड में बदलें और आप अपने खाते में लॉगिन कर सकते हैं केवल पहले 72 वर्णों में प्रवेश करना।

ब्लोफिश और काली मिर्च

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

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

तो मुझे लगता है कि पासवर्ड काली मिर्च कम से कम कोई बुरा विकल्प नहीं है।

सुझाव

72 से अधिक वर्ण (और काली मिर्च) वाले पासवर्ड के लिए ब्लॉफिश हैश प्राप्त करने का मेरा सुझाव है:

<?php
$pepper = "foIwUVmkKGrGucNJMOkxkvcQ79iPNzP5OKlbIdGPCMTjJcDYnR";

// Generate Hash
$password = "Wow. This is a super secret and super, super long password. Let's add some special ch4r4ct3rs a#d everything is fine :)";
$password_peppered = hash_hmac('sha256', $password, $pepper);
$hash = password_hash($password_peppered, PASSWORD_BCRYPT);

// Check
$input = substr($password, 0, 72);
$input_peppered = hash_hmac('sha256', $input, $pepper);

var_dump(password_verify($input_peppered, $hash));
?>

यह इस प्रश्न पर आधारित है: password_verify वापसी false

प्रश्न

सुरक्षित तरीका क्या है? पहले SHA-256 हैश प्राप्त करना (जो 64 वर्ण देता है) या पासवर्ड के पहले 72 वर्णों पर विचार करें?

पेशेवरों

  • उपयोगकर्ता केवल पहले 72 वर्ण दर्ज करके लॉगिन नहीं कर सकता है
  • आप वर्ण-सीमा से अधिक के बिना काली मिर्च जोड़ सकते हैं
  • हैश_हैमैक के आउटपुट में पासवर्ड की तुलना में शायद अधिक एन्ट्रॉपी होगी
  • पासवर्ड दो अलग-अलग कार्यों से धोया जाता है

विपक्ष

  • ब्लाफिश हैश बनाने के लिए केवल 64 वर्णों का उपयोग किया जाता है


1 संपादित करें: यह प्रश्न केवल blowfish / bcrypt के PHP एकीकरण को संबोधित करता है। टिप्पणियों के लिए धन्यवाद!


पेपरिंग पासवर्ड निश्चित रूप से करने के लिए एक अच्छी बात है, लेकिन देखते हैं क्यों।

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

फिर काली मिर्च वास्तव में क्या मदद करता है? जब तक काली मिर्च गुप्त रहता है, तब तक यह एक शब्दकोश हमले से कमजोर पासवर्ड की रक्षा करता है। पासवर्ड 1234 फिर 1234-p*deDIUZeRweretWy+.O जैसे कुछ बन जाएगा। 1234-p*deDIUZeRweretWy+.O । यह पासवर्ड केवल इतना लंबा नहीं है, इसमें विशेष वर्ण भी शामिल हैं और कभी भी किसी भी शब्दकोश का हिस्सा नहीं होंगे।

अब हम अनुमान लगा सकते हैं कि हमारे उपयोगकर्ता किस पासवर्ड का उपयोग करेंगे, शायद अधिक उपयोगकर्ता कमजोर पासवर्ड दर्ज करेंगे, क्योंकि 64-72 वर्णों के बीच पासवर्ड वाले उपयोगकर्ता हैं (वास्तव में यह बहुत दुर्लभ होगा)।

एक और बिंदु ब्रूट-फोर्सिंग की सीमा है। Sha256 हैश फ़ंक्शन 256 बिट्स आउटपुट या 1.2E77 संयोजनों को वापस कर देगा, जीपीयू के लिए भी ब्रूट-फोर्सिंग के लिए बहुत अधिक तरीके हैं (यदि मैंने सही ढंग से गणना की है, तो 2013 में जीपीयू पर 2E61 साल की आवश्यकता होगी)। इसलिए हमें मिर्च लगाने का वास्तविक नुकसान नहीं मिलता है। चूंकि हैश-वैल्यू व्यवस्थित नहीं हैं, इसलिए आप सामान्य पैटर्न के साथ ब्रूट-फोर्सिंग को तेज नहीं कर सकते हैं।

पीएस जहां तक ​​मुझे पता है, 72 वर्ण सीमा बीसीआरपीटी के एल्गोरिदम के लिए विशिष्ट है। मुझे मिला सबसे अच्छा जवाब this ।

पीपीएस मुझे लगता है कि आपका उदाहरण त्रुटिपूर्ण है, आप हैश को पूर्ण पासवर्ड लंबाई के साथ उत्पन्न नहीं कर सकते हैं, और इसे एक कटा हुआ एक के साथ सत्यापित कर सकते हैं। शायद आप हैश उत्पन्न करने और हैश के सत्यापन के लिए मिर्च को उसी तरह लागू करना चाहते थे।


Bcrypt महंगा Blowfish कुंजी सेटअप एल्गोरिदम के आधार पर एक एल्गोरिदम का उपयोग करता है।

Bcrypt के लिए अनुशंसित 56 बाइट पासवर्ड सीमा (शून्य समाप्ति बाइट समेत) Blowfish कुंजी की 448 बिट सीमा से संबंधित है। उस सीमा से परे किसी भी बाइट परिणामी हैश में पूरी तरह से मिश्रित नहीं हैं। Bcrypt पासवर्ड पर 72 बाइट पूर्ण सीमा इसलिए कम प्रासंगिक है, जब आप उन बाइट्स द्वारा परिणामी हैश पर वास्तविक प्रभाव पर विचार करते हैं।

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

बेशक, पासवर्ड टेबल के उल्लंघन के मामले में, हमें केवल उपयोगकर्ता के खाते को लॉक करने से पहले, उपयोगकर्ता के 55 बाइट पासवर्ड का अनुमान लगाने के दस प्रयासों को हैकर्स को अनुमति देना चाहिए;)

यदि आप 55 बाइट्स से अधिक पासवर्ड वाले प्री-हैश का निर्णय लेते हैं, तो आपको SHA-384 का उपयोग करना चाहिए, क्योंकि इसकी सीमा के बिना सबसे बड़ा आउटपुट है।





blowfish