क्या यह PHP में अच्छा हैशिंग पासवर्ड है? यदि नहीं, तो क्यों नहीं?




security passwords (4)

आपके द्वारा दिया गया कोड PHPASS का एक बंदरगाह है, विशेष रूप से "पोर्टेबल" एल्गोरिथम portable की योग्यता नोट करें यह केवल phpass लाइब्रेरी पर लागू होगा यदि आप दूसरे कन्स्ट्रक्टर पैरामीटर के रूप में true । इस उत्तर से बाहर से, phpass केवल पोर्टेबल एल्गोरिदम को संदर्भित करता है, और लाइब्रेरी स्वयं नहीं। पुस्तकालय डिफ़ॉल्ट रूप से बीक्रिप्ट कर देगा यदि आप स्पष्ट रूप से portable निर्दिष्ट नहीं करते हैं ...

PHPBB टीम ने इसे स्वयं विकसित नहीं किया (एक बहुत अच्छी बात), लेकिन इसे सीधे पाइप से (तर्कसंगत) रखा गया

हमें यहाँ कुछ सवाल पूछने चाहिए:

क्या यह खराब है?

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

कुछ कमजोरियों क्या हैं?

  • pbkdf2 लिए pbkdf2 phpass एल्गोरिथ्म hash() का उपयोग करता है जहां pbkdf2() का उपयोग करता है अब, एक एचएमएसी हर कॉल के लिए आंतरिक रूप से 2 हैश चलाता है, लेकिन PHP कार्यान्वयन केवल एक कॉल के कार्यान्वयन को लगभग 1.6 गुना hash() (अच्छा नहीं है?) है। इसलिए हमें hash_hmac से 2 हैश hash_hmac जो कि 62% समय में hash() लेता है।

    इसका क्या मतलब है? खैर, किसी दिए गए रनटाइम के लिए , pbkdf2 phpass एल्गोरिथम से लगभग 37.5% अधिक हैश phpass । किसी दिए गए समय में अधिक हैश == अच्छा है, क्योंकि इससे अधिक गणना की जा रही है।

    तो pbkdf2 लगभग 37.5% मजबूत होता है जब एक ही आदिम (इस मामले में md5 ) का उपयोग करते हुए। लेकिन pbkdf2 भी मजबूत प्राथमिकताएं ले सकता है। तो हम phpass एल्गोरिथम पर मुख्य लाभ के लिए sha512 साथ pbkdf2 इस्तेमाल कर सकते हैं (मुख्यतः क्योंकि sha512 md5 तुलना में अधिक गणना के साथ एक कठिन एल्गोरिथ्म है)।

    इसका अर्थ यह है कि न केवल pbkdf2 ही एक ही समय में अधिक कम्प्यूटेशन्स उत्पन्न करने में सक्षम है, यह कठिन कम्प्यूटेशन उत्पन्न करने में सक्षम है।

    उस ने कहा, अंतर काफी अधिक महत्वपूर्ण नहीं है यह बहुत अधिक मापने योग्य है, और pbkdf2 निश्चित रूप से "मजबूत" से अधिक है।

  • bcrypt करने के लिए bcrypt : यह करने के लिए तुलना की एक बहुत कठिन है। लेकिन हम इसे की सतह को देखते हैं phpass md5 का उपयोग करता है, और PHP में एक पाश। pbkdf2 किसी भी आदिम (सी में) और PHP में एक पाश का उपयोग करता है। bcrypt सी में सभी कस्टम एल्गोरिथम का उपयोग करता है (जिसका अर्थ है कि यह किसी भी उपलब्ध हैश से अलग एल्गोरिदम है)। तो बल्ले का सही, bcrypt का एक महत्वपूर्ण फायदा है, केवल यह तथ्य है कि एल्गोरिथ्म सी में है। यह प्रति यूनिट समय में अधिक "गणना" के लिए अनुमति देता है। जिससे यह इसे और अधिक कुशल धीमा एल्गोरिदम (दिए गए क्रम में अधिक कंप्यूटिंग) बनाते हैं।

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

    bcrypt की अधिक मजबूत प्रकृति का एक उदाहरण यह है कि bcrypt सामान्य हैश फ़ंक्शन के मुकाबले एक बहुत बड़ा आंतरिक राज्य का उपयोग करता है। SHA512 1024 बिट्स के ब्लॉक के विरुद्ध गणना करने के लिए 512 बिट आंतरिक स्थिति का उपयोग करता है। 576 बिट्स के एक ब्लॉक के खिलाफ गणना करने के लिए bcrypt आंतरिक स्थिति के बजाय 32kb का उपयोग करता है। तथ्य यह है कि bcrypt का आंतरिक राज्य SHA512 (और md5 और phpass ) की तुलना में बहुत बड़ा है आंशिक रूप से phpass की मजबूत प्रकृति के लिए bcrypt

क्या इसे टालना चाहिए

नई परियोजनाओं के लिए, बिल्कुल । ऐसा नहीं है कि यह बुरा है। ऐसा नहीं है। ऐसा लगता है कि वहाँ (मजबूतता के आदेश के द्वारा) वहाँ demonstrably मजबूत एल्गोरिदम हैं तो उन्हें क्यों नहीं उपयोग करें?

कैसे bcrypt मजबूत है के आगे सबूत के लिए, पासवर्ड 13 (पीडीएफ) से स्लाइड देखें जो पासवर्ड हैश क्रैक करने के लिए 25 GPU क्लस्टर लॉन्च करता है यहां प्रासंगिक परिणाम दिए गए हैं:

  • md5($password)
    • 180 बिलियन अनुमान प्रति सेकंड
    • 9.4 घंटे - सभी संभव 8 अक्षर पासवर्ड
  • sha1($password)
    • 61 बिलियन अनुमान प्रति सेकंड
    • 27 घंटे - सभी संभव 8 अक्षर पासवर्ड
  • md5crypt (जो 10 की लागत के साथ phpass के समान है):
    • 77 मिलियन अनुमान प्रति सेकंड
    • 2.5 साल - सभी संभव 8 अक्षर पासवर्ड
  • 5 लागत के साथ bcrypt
    • 71 हजार अनुमान प्रति सेकंड
    • 2700 वर्ष - सभी संभव 8 अक्षर पासवर्ड

नोट: सभी संभव 8 वर्ण पासवर्ड 94 वर्ण सेट का उपयोग कर रहे हैं:

a-zA-Z0-9~`[email protected]#$%^&*()_+-={}|[]\:";'<>,.?/

तल - रेखा

इसलिए यदि आप नया कोड लिख रहे हैं, बिना किसी संदेह का उपयोग करें bcrypt अगर आपके पास अब उत्पादन में phpass या pbkdf2 है, तो आप अपग्रेड करना चाह सकते हैं, लेकिन यह स्पष्ट कटौती नहीं है "आप काफी कमजोर हैं"।

मैं सोच रहा हूं कि यह फ़ंक्शन (जो कि ~ 2 साल पुराने पीपीबीबी संस्करण से लिया गया है), यह काफी अच्छा है।

यदि नहीं, तो क्यों?
और आप इसे कैसे बदल सकते हैं (विद्यमान उपयोगकर्ताओं के लिए संक्रमण को निर्बाध बनाते हैं)?

हैश_पीडब्ल्यूडी () का नतीजा है जो डीबी में बचाया जाएगा।

function hash_pwd($password)
{
    $itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';

    $random_state = $this->unique_id();
    $random = '';
    $count = 6;

    if (($fh = @fopen('/dev/urandom', 'rb')))
    {
        $random = fread($fh, $count);
        fclose($fh);
    }

    if (strlen($random) < $count)
    {
        $random = '';

        for ($i = 0; $i < $count; $i += 16)
        {
            $random_state = md5($this->unique_id() . $random_state);
            $random .= pack('H*', md5($random_state));
        }
        $random = substr($random, 0, $count);
    }

    $hash = $this->_hash_crypt_private($password, $this->_hash_gensalt_private($random, $itoa64), $itoa64);

    if (strlen($hash) == 34)
    {
        return $hash;
    }

    return false;
}


function unique_id()
{
    $val = microtime();
    $val = md5($val);

    return substr($val, 4, 16);
}

function _hash_crypt_private($password, $setting, &$itoa64)
{
    $output = '*';

    // Check for correct hash
    if (substr($setting, 0, 3) != '$H$')
    {
        return $output;
    }

    $count_log2 = strpos($itoa64, $setting[3]);

    if ($count_log2 < 7 || $count_log2 > 30)
    {
        return $output;
    }

    $count = 1 << $count_log2;
    $salt = substr($setting, 4, 8);

    if (strlen($salt) != 8)
    {
        return $output;
    }

    /**
    * We're kind of forced to use MD5 here since it's the only
    * cryptographic primitive available in all versions of PHP
    * currently in use.  To implement our own low-level crypto
    * in PHP would result in much worse performance and
    * consequently in lower iteration counts and hashes that are
    * quicker to crack (by non-PHP code).
    */
    if (PHP_VERSION >= 5)
    {
        $hash = md5($salt . $password, true);
        do
        {
            $hash = md5($hash . $password, true);
        }
        while (--$count);
    }
    else
    {
        $hash = pack('H*', md5($salt . $password));
        do
        {
            $hash = pack('H*', md5($hash . $password));
        }
        while (--$count);
    }

    $output = substr($setting, 0, 12);
    $output .= $this->_hash_encode64($hash, 16, $itoa64);

    return $output;
}

function _hash_gensalt_private($input, &$itoa64, $iteration_count_log2 = 6)
{
    if ($iteration_count_log2 < 4 || $iteration_count_log2 > 31)
    {
        $iteration_count_log2 = 8;
    }

    $output = '$H$';
    $output .= $itoa64[min($iteration_count_log2 + ((PHP_VERSION >= 5) ? 5 : 3), 30)];
    $output .= $this->_hash_encode64($input, 6, $itoa64);

    return $output;
}

function _hash_encode64($input, $count, &$itoa64)
{
    $output = '';
    $i = 0;

    do
    {
        $value = ord($input[$i++]);
        $output .= $itoa64[$value & 0x3f];

        if ($i < $count)
        {
            $value |= ord($input[$i]) << 8;
        }

        $output .= $itoa64[($value >> 6) & 0x3f];

        if ($i++ >= $count)
        {
            break;
        }

        if ($i < $count)
        {
            $value |= ord($input[$i]) << 16;
        }

        $output .= $itoa64[($value >> 12) & 0x3f];

        if ($i++ >= $count)
        {
            break;
        }

        $output .= $itoa64[($value >> 18) & 0x3f];
    }
    while ($i < $count);

    return $output;
}

मैं बीक्रिप्ट के लिए जाता हूं। यह अच्छा है, इंद्रधनुष तालिका के हमलों से बचाने के लिए नमक को शामिल करने के अलावा, बीक्रिप्ट एक अनुकूली कार्य है: समय के साथ, चलने की गणना को धीमा बनाने के लिए बढ़ाया जा सकता है, इसलिए यह ब्रूट बल खोज हमलों यहां तक ​​कि बढ़ती गणना शक्ति के साथ

कार्यान्वयन: आप PHP में हैशिंग पासवर्ड के लिए bcrypt का उपयोग कैसे करते हैं?


शीघ्र जवाब:

Bcrypt का उपयोग करें (जब यह तैयार है) या पासवर्ड_compat लाइब्रेरी से ircmaxell - यह एक bcrypt पुस्तकालय है

लंबा जवाब:

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

आप खुद से पूछ सकते हैं कि वह विशिष्ट पुस्तकालय क्यों है? वैसे ही फ़ंक्शंस php 5.5 में उपलब्ध होंगे, ताकि आपको किसी भी कोडिंग को बदलना पड़े। शुभकामनाएं और इसे सरल और कुशल रखना लॉगिंग इन और पासवर्ड सामग्री के लिए भी धीमा अच्छा है

अपडेट 1

@ गुंबो -> कोई MD5 टूटा हुआ नहीं है, लेकिन MD5 की तरह अब और पूर्व में हैश का मुख्य उद्देश्य फाइल चेकिंग के लिए था (जैसा कि आप यह जानना जानते हैं कि फाइल की सामग्री विश्वसनीय पासवर्ड नहीं भरी जा सकती है) क्योंकि हैश बहुत हैं समझने के लिए जल्दी क्योंकि आप 30 से 45 सेकेंड तक इंतजार करते समय फ़ाइल की सामग्री की जांच करने के लिए बीक्र्रीप का उपयोग नहीं करेंगे ... तो इसका मतलब है कि एक हैश विशेष रूप से जल्दी से पढ़ने के लिए होता था बीसीआरपीटी की तुलना में भी एक SHA512 अभी भी पूरी तरह से नीच है। यही वजह है कि PHP में ब्लॉफिश / बीक्रिप्ट जैसे मजबूत पासवर्ड एल्गोरिदम को दबाए जाने के लिए आवश्यक है। हम जैसे ही प्रयोक्ता और प्रोग्रामर के समान ज्ञान का विस्तार करना चाहिए, जो सादा पासवर्ड भंडारण या निम्न स्तर हैशिंग एल्गोरिदम उत्तर नहीं हैं - और इन संवेदनशील सूचनाओं के लिए कभी भी उपयोग नहीं किया जाना चाहिए।

अब ओपी से आपके सिस्टम को नए सिस्टम पर स्थानांतरित करने के लिए आप पहले सभी उपयोगकर्ताओं को एक सूचना भेजेंगे कि "आपकी सुरक्षा के लिए पासवर्ड एन्क्रिप्शन सिस्टम अपडेट हो गया है ........", तो आप उन्हें पूछेंगे एक बार पासवर्ड अपडेट करने के लिए, पासवर्ड अपडेट करने के बाद आप पासवर्ड की पुष्टि करते हुए फ़ंक्शन का प्रयोग करेंगे और यदि आप अपने लागत अनुपात का अधिकतम नियंत्रण चाहते हैं तो आप password_needs_rehash का उपयोग करते हैं, अगर आप पासवर्ड के साथ जुड़े लागत को बदलने के लिए चुनते हैं ।

यह ऐसा करने के लिए कोड का एक बड़ा ब्लॉक नहीं लेगा क्योंकि आपको पास शब्द सुरक्षा में मिले लाभ के बारे में नए पासवर्ड सिस्टम को "याद दिलाना" होने के नकारात्मक नतीजों पर ध्यान देना होगा।

उम्मीद है कि यह अधिकांश प्रश्नों का उत्तर देता है, लेकिन कम से कम कोई भी IRCmaxell का उत्तर अलग-अलग अल्गोरिदम पर विस्तार से आगे नहीं बढ़ रहा है! भाग्य के सर्वश्रेष्ठ ओपी, और आईआरसीएमएक्सेल के लिए बहुत बड़ा धन्यवाद!

अपडेट 2

इसके अलावा, क्या इस तरह एक पासवर्ड संग्रहीत वास्तव में crackable होगा? कैसे? (मैं अब उत्सुक हूँ)

किसी भी चीज और सब कुछ टूट गया है जो मेरा नेटवर्क सुरक्षा प्रोफेसर मुझसे कहता है .. मैं उस पर हँसे। अब जब मैं चीजों को उसकी आंखों में देखता हूं ... अच्छा हां .. यह बिल्कुल सही है!

Bcrypt वर्तमान में पासवर्ड संचय करने का सबसे अच्छा तरीका है! हालांकि अगर आप स्क्रिप पर गौर करते हैं जो आशाजनक लगता है, लेकिन PHP द्वारा समर्थित नहीं है कोई भी कम नहीं है और सब कुछ टूट गया है, यह सिर्फ समय की बात है जब तक एक तहखाने में कुछ "geek" बीक्रिप्ट दरार जाएगा लेकिन अब हम सुरक्षित हैं .. जैसे कि हम आईपीवी 4 के साथ कभी भी सुरक्षित नहीं हैं .... ओह रुको? ...;)

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


(सबसे पहले मेरे अंग्रेजी के लिए क्षमा करें)

कुछ सवाल हैं, जो सभी टिप्पणीकारों को जवाब देने से पहले पूछना है:

वह कोड कहां उपयोग किया जाएगा?

यह किस तरह का डेटा रक्षा करेगा?

क्या यह महत्वपूर्ण स्तर के सिस्टम के लिए इस्तेमाल किया जाएगा?

ठीक है हमारे पास कुछ उपयोग-केस हैं I मैं आईएस के लिए सरलीकृत पासवर्ड जेनरेटर का उपयोग कर रहा हूं, हाँ, यह वास्तव में 'तीसरा विश्व युद्ध तैयार' नहीं है, लेकिन मौका, कि उपयोगकर्ता किसी को पासवर्ड बताएगा, या उसके कंप्यूटर से कुछ मैलवेयर द्वारा लीक किया जाएगा अभी भी बहुत बड़ा है

  • एमडी 5 कमजोर है, नवीनतम फिंगरप्रिंट जनरेटर का उपयोग करें (शा 128, शा 256, शाए 512)
  • यादृच्छिक लंबाई नमक का उपयोग करें जैसे:

    private function generateSalt() {
      $salt = '';
      $i = rand(20, 40); //min,max length
      for($length = 0; $length < $i; $length++) {
        $salt .= chr(rand(33, 126));
      }        
      return $salt;
    }
  • फिर कुछ पासवर्ड उत्पन्न करें:

    private function generatePass() {
      $vocabulary = 'abcdefghijklmnopqrstuvwxyz0123456789';
      $password = '';
      $i = rand(7,10);
      for($length = 0; $length < $i; $length++) {
          $password .= substr($vocabulary,rand(0, 35),1);
      }        
      return $password.'-'; // avoid copy`n`paste :)
    }
  • हाँ पासवर्ड मजबूत होना चाहिए, लेकिन उपयोगकर्ता इसे कभी भी याद नहीं करेगा, यह ब्राउज़र में सहेजा जाएगा या कहीं लिखा होगा। अपेक्षाओं और सुरक्षा बनाम वास्तविकता

    $newSalt = $this->generateSalt();
    $newPass = $this->generatePass();
    $newHash = hash('sha512', $newPass.':'.$newSalt); 
    // now store hash and salt into database
  • नया हैश है, लेकिन यह खत्म नहीं हुआ है, सही काम शुरू हो गया है:

    1. लॉगिंग
    2. सत्र की रक्षा करना
    3. उपयोगकर्ता, उपयोगकर्ता + आईपी, आईपी अस्थायी / परम प्रतिबंध
    4. आदि

लॉगिन + लॉगआउट + पुन: उत्पन्न / पासवर्ड: 1 या 2 एसक्यूएल टेबल और कोड के कुछ केबी

सुरक्षा के बारे में अन्य चीजें: कई तालिकाओं, वास्तव में कोड के कुछ केबी से अधिक





password-hash