2009-01-28 23 views
5

कोई यह देखने के लिए कैसे जांचता है कि उपयोगकर्ता ने लॉग इन करने के लिए सही पासवर्ड टाइप किया है या नहीं? वहाँ कुछ mysql_result बिट में गलत क्या हैPHP और MySQL पासवर्ड की तुलना करें

<? 

$login = $_POST['login']; 
$password = $_POST['password']; 

mysql_connect('localhost', 'root', 'abc123'); 

mysql_select_db('aun_vox') or die(mysql_error()); 

$q = mysql_query("SELECT password FROM customer WHERE login='$login'"); 
$db_pass = mysql_result($q, 0); 

if(md5($password) == $db_pass) 
{ 
    echo "You did it."; 
} 

else echo "Wrong."; 

?> 

मैं ouput से देख सकते हैं, लेकिन मैं नहीं कर सकता:

यह मैं क्या (संयोजन का एक समूह से बाहर ...) कर रहा हूँ है सही तरीके से पता लगाएं।

क्या कोई मदद कर सकता है।

+3

हम यहाँ stackoverflow पर लॉगिन के बारे में सवालों का जवाब नहीं है। हम महान तकनीकी विवरण में, उपयोगकर्ता इनपुट को स्वच्छ करने के तरीके को समझाना पसंद करते हैं। काम करने वाली वेबसाइट की तुलना में सुरक्षित होना बेहतर है। – Grant

+5

@ अनुदान: आप मजाक कर रहे हैं, है ना? –

+0

ध्यान रखें कि इस पृष्ठ के उत्तरों पुराने हैं और इसलिए असुरक्षित हैं, इसके बजाय [प्रश्न] (http://stackoverflow.com/q/4795385/575765) पर एक नज़र डालें। – martinstoeckli

उत्तर

17

मुझे लगता है कि आप डेटाबेस में पासवर्ड का हैश संग्रहीत कर रहे हैं, लेकिन अन्य पाठकों के लाभ के लिए, डेटाबेस में सादा पाठ में स्टोर पासवर्ड कभी नहीं। आप like Monster.com.uk नहीं बनना चाहते हैं!

आपको MD5() से अधिक मजबूत हैशिंग फ़ंक्शन का उपयोग करना चाहिए। आदर्श रूप से आपको SHA256 का उपयोग करना चाहिए। यह हैश विधि hash() फ़ंक्शन का उपयोग करके PHP में उपलब्ध है।

आपको पासवर्ड पर एक यादृच्छिक salt भी लागू करना चाहिए। प्रत्येक उपयोगकर्ता के खाते के लिए एक अलग नमक मूल्य स्टोर करें। यह शब्दकोश हमलों और rainbow table हमलों को हराने में मदद करता है।

आपको पुराने mysql एक्सटेंशन के बजाय mysqli एक्सटेंशन का उपयोग करना सीखना चाहिए। Mysqli पैरामीटरयुक्त प्रश्नों का समर्थन करता है, ताकि आप कुछ एसक्यूएल इंजेक्शन हमलों के लिए भेद्यता को कम कर सकें।

यहां कुछ उदाहरण कोड है। मैं यह परीक्षण किया है नहीं है, लेकिन यह बहुत काम कर के करीब होना चाहिए:

$input_login = $_POST['login']; 
$input_password = $_POST['password']; 

$stmt = $mysqli->prepare("SELECT password, salt FROM customer WHERE login = ?"); 
$stmt->bind_param("s", $input_login); 
$stmt->execute(); 
$stmt->bind_result($password_hash, $salt); 

while ($stmt->fetch()) { 
    $input_password_hash = hash('sha256', $input_password . $salt); 
    if ($input_password_hash == $password_hash) { 
    return true; 
    } 
    // You may want to log failed password attempts here, 
    // for security auditing or to lock an account with 
    // too many attempts within a short time. 
} 
$stmt->close(); 

// No rows matched $input_login, or else password did not match 
return false; 

कुछ अन्य लोगों का सुझाव क्वेरी login = ? AND password = ? के लिए परीक्षण करना चाहिए, लेकिन मुझे लगता है कि ऐसा करने के लिए पसंद नहीं है। यदि आप ऐसा करते हैं, तो आप नहीं जानते कि लुकअप विफल हुआ है क्योंकि लॉगिन मौजूद नहीं था, या क्योंकि उपयोगकर्ता ने गलत पासवर्ड प्रदान किया था।

बेशक आपको उस उपयोगकर्ता को प्रकट नहीं करना चाहिए जिसने असफल लॉगिन प्रयास किया है, लेकिन आपको जानने की आवश्यकता हो सकती है, ताकि आप संदिग्ध गतिविधि लॉग कर सकें।


@Javier अपने जवाब में कहा गया है कि आप डेटाबेस से पासवर्ड (या इस मामले में पासवर्ड हैश) को पुनः प्राप्त नहीं करना चाहिए। मैं सहमत नहीं हूँ।

जेवियर PHP कोड में md5() पर कॉल करना और परिणामस्वरूप हैश स्ट्रिंग डेटाबेस को भेज रहा है। लेकिन यह आसानी से पासवर्ड को सलाम करने का समर्थन नहीं करता है। PHP में हैश करने से पहले आपको इस उपयोगकर्ता के नमक को पुनः प्राप्त करने के लिए एक अलग क्वेरी करना है।

विकल्प plaintext अपने PHP ऐप से अपने डेटाबेस सर्वर पर नेटवर्क पर पासवर्ड भेज रहा है। आपके नेटवर्क को वायरटैप करने वाला कोई भी व्यक्ति इस पासवर्ड को देख सकता है। यदि आपके पास SQL ​​क्वेरी लॉग इन हैं, तो जो भी लॉग तक पहुंच प्राप्त करता है वह पासवर्ड देख सकता है। प्रेरित हैकर पुरानी फाइल सिस्टम बैकअप मीडिया खोजने के लिए डंपस्टर-डाइव भी कर सकते हैं, और लॉग फाइलें इस तरह से पढ़ सकते हैं!

डेटाबेस से पासवर्ड हैश स्ट्रिंग को PHP ऐप में लाने का कम जोखिम है, इसे उपयोगकर्ता के इनपुट (PHP कोड में भी) के हैश से तुलना करें, और फिर इन चर को छोड़ दें।

+0

आपके कोड में केवल एक चीज गायब थी। mysqli_prepare() दो पैरामीटर लेता है - पहला mysqli_connect() कथन का परिणाम है। चूंकि मैं इसके बजाय mysql_connect() का उपयोग कर रहा था, यह काम नहीं कर रहा था। लेकिन संशोधन के बाद, यह ठीक काम करता है। आपकी सहायता के लिए धन्यवाद. – Mussnoon

+0

पकड़ने के लिए धन्यवाद, मैंने इसे ठीक कर दिया है। हालांकि, मैंने डेटाबेस से कनेक्ट नहीं दिखाया। बस माना जाता है कि आपके पास लाइव $ mysqli ऑब्जेक्ट है। –

+0

mysqli उपयोग करने के लिए बहुत ही भयंकर bugg है (दुख की बात है) – cletus

1

कुछ अंक:

  • क्वेरी स्ट्रिंग में स्ट्रिंग डेटा न डालें। विशेष रूप से उपयोगकर्ता द्वारा प्रदत्त डेटा। क्या होगा यदि मैं "रॉबर्ट" के साथ लॉगिन करता हूं; ड्रॉप टेबल ग्राहक "? या तो बचने के दिनचर्या का उपयोग करें, या (कहीं बेहतर) तैयार बयान और बाध्य पैरामीटर का उपयोग करें।
  • अपने डेटाबेस में cleartext पासवर्ड स्टोर न करें। (आप इस पर ठीक हैं)
  • अपने डेटाबेस से पासवर्ड पुनर्प्राप्त नहीं करें।

क्या मैं आमतौर पर करते हैं की तरह कुछ है:

$q = preparestatement ("SELECT id FROM customer WHERE login=? AND password=?"); 
bindvalue ($q, $_POST['login']); 
bindvalue ($q, md5($_POST['password'])); 
$id = execprepared ($q); 

if($id) { 
    echo "You did it."; 
} else { 
    echo "Wrong."; 
} 
+1

हम उसे छोटे बॉबी टेबल्स कहते हैं। – Powerlord

+3

आपको शायद यह इंगित करना चाहिए कि आप मूल PHP कोड का उपयोग नहीं कर रहे हैं। bindvalue() मुझे थोड़ा उलझन में था, और php.net पर इसे खोजने में विफल होने के बाद भी और भी बहुत कुछ। अंत में PHP डेटा ऑब्जेक्ट्स (पीडीओ) ऑनलाइन मिला जो आपके उदाहरण में जानकारी को कवर करता था। – Sampson

2

सबसे पहले, सुनिश्चित करें कि आप ठीक से उन क्वेरी में उपयोग करने से पहले अपने चर बच बनाने - उपयोग mysql_real_escape_string()।

फिर, अपनी क्वेरी में वैध लॉगिन की जांच के लिए MySQL MD5 फ़ंक्शन का उपयोग क्यों न करें?

SELECT login FROM customer WHERE login='$login' AND password = MD5('$password') 

फिर वापस पंक्तियों की संख्या की गणना करने के लिए mysql_num_rows() का उपयोग करें।

0

फ़ॉर्म पोस्ट विधि से उपयोगकर्ता से पासवर्ड प्राप्त करें और कन्वर्ट $ _POST [ 'पासवर्ड'] // रूप से // php/jsp में उचित प्रारूप में/किसी अन्य फिर अपने डेटाबेस में स्वरूपित पासवर्ड के साथ तुलना

आम तौर पर md5 एन्क्रिप्शन का उपयोग तब किया जाता है जब आप md45 ('{$ _ POST [' password ']}') = अपने डीबी में मौजूद की तुलना कर सकते हैं; पासवर्ड बनाने के दौरान या आमतौर पर mysql पासवर्ड ('आपका पासवर्ड') कमांड का उपयोग करें, इसलिए पहले एन्क्रिप्टेड पासवर्ड मान प्राप्त करने के लिए mysqli_query और mysqli_fetch_array में अपने $ _POST ['password'] को कॉन्सर्ट करें और फिर तुलना करें।

0

PHP 5.6 से ग्रेटर, आप हैश_कंपारे फ़ंक्शन का उपयोग कर सकते हैं।

$users_password = hash(sha256,$salt.$post_password); 

if (hash_equals($users_dbpassword, $users_password)) { 
     //pass is good 
} else { 
     // pass failed 
} 

http://php.net/manual/ru/function.hash-equals.php

+1

असल में इस फ़ंक्शन का उपयोग पासवर्ड हैश की तुलना करने के लिए नहीं किया जाना चाहिए (तुलनात्मक हैश पासवर्ड के लिए उपयुक्त नहीं हैं), इसके बजाय [password_verify()] (http://www.php.net/manual/en/function.password-verify] का उपयोग करें। php) और हैश उत्पन्न करें [password_hash()] (http://www.php.net/manual/en/function.password-hash.php)। – martinstoeckli

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