2013-02-21 60 views
31

कहें कि मैं किसी उपयोगकर्ता के लिए पासवर्ड स्टोर करना चाहता हूं, क्या यह PHP 5.5 के password_hash() फ़ंक्शन (या PHP 5.3.7+ के लिए यह संस्करण) के साथ ऐसा करने का सही तरीका होगा: https://github.com/ircmaxell/password_compat)?PHP 5.5 के पासवर्ड_शैश और पासवर्ड_verify फ़ंक्शन का उपयोग

$options = array("cost" => 10, "salt" => uniqid()); 
$hash = password_hash($password, PASSWORD_BCRYPT, $options); 

तो मैं करना होगा:

mysql_query("INSERT INTO users(username,password, salt) VALUES($username, $hash, " . $options['salt']); 

डेटाबेस में सम्मिलित करने के लिए।

तो सत्यापित करने के लिए:

$row = mysql_fetch_assoc(mysql_query("SELECT salt FROM users WHERE id=$userid")); 
$salt = $row["salt"]; 
$hash = password_hash($password, PASSWORD_BCRYPT, array("cost" => 10, "salt" => $salt)); 

if (password_verify($password, $hash) { 
    // Verified 
} 
+1

हम्म, वहाँ कुछ यहाँ अजीब है, तो आप सरणी है –

+0

फिक्स्ड, क्षमा करें। –

+0

आप अभी भी एक नहीं दिया है)? इसके अलावा आप 'ext/mysql' का उपयोग कर रहे हैं, जो 5.5 में बहिष्कृत है मुझे लगता है कि –

उत्तर

57

अब के लिए अपने डेटाबेस बयान के साथ मुद्दों की अनदेखी कर, मैं password_hash के बारे में सवाल का जवाब देंगे।

संक्षेप में, नहीं, ऐसा नहीं है कि आप इसे कैसे करते हैं। आप अकेले नमक को स्टोर नहीं करना चाहते हैं, आपको हैश और नमक दोनों को संग्रहित करना चाहिए, और फिर पासवर्ड को सत्यापित करने के लिए दोनों का उपयोग करना चाहिए। password_hash दोनों युक्त एक स्ट्रिंग देता है।

password_hash फ़ंक्शन एक स्ट्रिंग देता है जिसमें हैश और नमक दोनों शामिल हैं। तो:

$hashAndSalt = password_hash($password, PASSWORD_BCRYPT); 
// Insert $hashAndSalt into database against user 

तो सत्यापित करने के लिए:

// Fetch hash+salt from database, place in $hashAndSalt variable 
// and then to verify $password: 
if (password_verify($password, $hashAndSalt)) { 
    // Verified 
} 

इसके अतिरिक्त, के रूप में टिप्पणी, सुझाव है कि अगर आप सुरक्षा में आपकी रुचि आप mysqli को देखने के लिए चाहते हो सकता है (ext/mysql PHP5.5 में पदावनत किया गया है) , और यह आलेख एसक्यूएल इंजेक्शन पर भी है: http://php.net/manual/en/security.database.sql-injection.php

+0

क्या आप सुझाव दे रहे हैं कि वह नमक तंत्र का उपयोग करें, लेकिन नमक को स्टोर न करें? यदि हां, तो मूल हैश बनाने के लिए उपयोग किए जाने वाले मूल नमक को आप कैसे प्राप्त करेंगे, जिस पर यह जांचने के लिए कि जब उपयोगकर्ता लॉग इन करने का प्रयास करता है? –

+1

नमक और हैश एक स्ट्रिंग में password_hash द्वारा एक साथ लौटाए जाते हैं। – Pete

+0

जब आप कहते हैं कि अब आप डेटाबेस स्टेटमेंट के साथ समस्याओं को अनदेखा करेंगे, तो क्या पोस्ट के निचले हिस्से में उल्लेखित मुद्दे थे? –

4

आपको अपने नमक में प्रवेश नहीं करना चाहिए, नमक खाली छोड़ना चाहिए, कार्य अच्छा यादृच्छिक नमक उत्पन्न करेगा।

फ़ंक्शन द्वारा लौटाई गई संपूर्ण स्ट्रिंग डेटाबेस (या फ़ाइल या जो भी आप उपयोग करते हैं) में डालें। इसमें शामिल हैं: एल्गोरिदम, लागत, नमक (22 वर्ण) और हैश पासवर्ड की आईडी।

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

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

$hash = password_hash($password, PASSWORD_BCRYPT, array("cost" => 10)); 

आप इस पैरामीटर अपने सर्वर पर गति की जांच के आधार पर स्थापित करना चाहिए एक हैश उत्पन्न करने के लिए की जरूरत है। यह अनुशंसा की जाती है कि समारोह ने 100ms + (कुछ इसे 250 एमएस बनाना पसंद करते हैं) का प्रदर्शन किया। आम तौर पर लागत = 10 या 11 एक अच्छी पसंद है (2015 में)।

सुरक्षा बढ़ाने के लिए, आप पासवर्ड में लंबे समय तक जोड़ना चाहेंगे (50-60 वर्ण अच्छी पसंद है) गुप्त स्ट्रिंग। पासवर्ड_शैश() या password_verify() का उपयोग करने से पहले।

$secret_string = '[email protected]#[email protected]#$234'; 
$password = trim($_POST['user_password']) . $secret_string; 
// here use password_* function 

सावधानी algo पैरामीटर के लिए PASSWORD_BCRYPT का उपयोग करना, पासवर्ड पैरामीटर में परिणाम 72 वर्णों की अधिकतम लंबाई को छोटा कर दिया जा रहा होगा।

यदि $ 72 72 वर्णों से अधिक लंबा होगा और आप 73 या 90 वर्ण बदलते हैं या जोड़ते हैं तो हैश नहीं बदलेगा। वैकल्पिक, $ secret_string चिपकाना अंत में होना चाहिए (उपयोगकर्ता के पासवर्ड के बाद और पहले नहीं)।

6

नोट इस php.net

चेतावनी

नमक विकल्प से पीएचपी 7.0.0 के रूप में मान्य नहीं है। अब यह डिफ़ॉल्ट रूप से जेनरेट किए गए नमक का उपयोग करना पसंद करता है।

निष्कर्ष? नमक विकल्प के बारे में भूल जाओ।

यह काफी पर्याप्त password_hash('password', PASSWORD_DEFAULT) * (या _BCRYPT)

9

उपयोग कर अपने खुद नमक अनुशंसित नहीं है और, पीएचपी 7, its use is deprecated के रूप में किया जाएगा। क्यों समझने के लिए, read the author's thoughts

एक बात बहुतायत से मेरे लिए स्पष्ट हो गया: नमक विकल्प खतरनाक है। मुझे अभी तक नमक विकल्प का एक भी उपयोग नहीं देखा गया है जिसमें भी सभ्य है। प्रत्येक उपयोग खराब से होता है (mt_rand() आउटपुट) को पागल करने के लिए खतरनाक (स्थैतिक तार) तक गुजरना (पासवर्ड को अपने नमक के रूप में पास करना)।

मैं इस निष्कर्ष पर आया हूं कि मुझे नहीं लगता कि हमें नमक निर्दिष्ट करने के लिए उपयोगकर्ताओं को की अनुमति देनी चाहिए।

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^