使用Bcrypt密码验证登录

4

我有一个网站正在使用bcrypt编写注册/登录系统。我已经成功地将注册详细信息和哈希密码插入到数据库中。我的问题是如何使用这个哈希密码来验证用户。以下是我使用的代码:

注册操作:

<? ob_start();//Start buffer output ?>
<html>
<head>
<title>MySite: Registration Action</title>
</head>
<font face="arial">

<?php

session_start();
if(isset($_POST["captcha"])&&$_POST["captcha"]!=""&&$_SESSION["code"]==$_POST["captcha"])
{
//echo "Correct Code Entered";
//Do req stuff







$host="host"; // Host name 
$username="username"; // Mysql username 
$password="password"; // Mysql password 
$db_name="db"; // Database name 
$tbl_name="tbl"; // Table name 

// Connect to server and select database.
mysql_connect("$host", "$username", "$password")or die("cannot connect"); 
mysql_select_db("$db_name")or die("cannot select DB");

// Get values from form 
$myusername=mysql_real_escape_string($_POST['myusername']);
$mypassword=mysql_real_escape_string($_POST['mypassword']);
$myemail=mysql_real_escape_string($_POST['myemail']);
$mysecrquest=mysql_real_escape_string($_POST['mysecrquest']);
$mysecransw=mysql_real_escape_string($_POST['mysecransw']);
$mypassword_rep=mysql_real_escape_string($_POST['mypassword_rep']);
$myemail_rep=mysql_real_escape_string($_POST['myemail_rep']);
$mysecransw_rep=mysql_real_escape_string($_POST['mysecransw_rep']);

$salt = '$2a$18$' . substr(md5(uniqid(rand(), true)), 0, 22);

$encpass = crypt($mypassword, $salt);

//validate input
if (( !empty($myusername) && !empty($mypassword) && !empty($myemail) && !empty($mysecrquest) && !empty($mysecransw) )
&& (($mypassword_rep==$mypassword)&&($myemail_rep==$myemail)&&($mysecransw_rep==$mysecransw)))
{
// Insert data into mysql 
$sql="INSERT INTO $tbl_name(username, salt, password, email, secrquest, secransw)VALUES('$myusername', '$salt', '$encpass', '$myemail', '$mysecrquest', 

'$mysecransw')";
$result=mysql_query($sql);

// if successfully insert data into database, displays message "Successful". 
if($result){
echo "<center><font color='green'>Congratulations! Your registration was Successful</font></center>";
echo "<BR>";
echo "<center><a href='somepage.php'>Somepage</a></center>";
}
}

else {
echo "<center><font color='red'>You have one or more invalid entries: Your Registration was not successful</font></center>";
echo "<br>";
echo "<center><a href='regpage.php'>Back</a></center>";
}


}
else {
echo "<center><font color='red'>Wrong Captcha: Your Registration was not successful</font></center>";
echo "<br>";
echo "<center><a href='regpage.php'>Back</a></center>";
}

?> 



<?php 
// close connection 
//mysql_close();
?>

</font>
</html>
<? ob_flush();//Flush buffer output ?>

登录操作:

<? ob_start();//Start buffer output ?>
<html>
<head>
<title>MySite: Login Action</title>
</head>

<font face="arial">

<?php
session_start();
if(isset($_POST["captcha"])&&$_POST["captcha"]!=""&&$_SESSION["code"]==$_POST["captcha"])
{
// echo "<font color='green'>Correct Code Entered</font>";
//Do req stuff





$host="host"; // Host name 
$username="username"; // Mysql username 
$password="password"; // Mysql password 
$db_name="db"; // Database name 
$tbl_name="tblx"; // Table name 
$tbl_name2="tbl"; // Table name 2

// Connect to server and select database.
mysql_connect("$host", "$username", "$password")or die("cannot connect"); 
mysql_select_db("$db_name")or die("cannot select DB");

// Get values from form 
$myusername=mysql_real_escape_string($_POST['myusername']);
$mypassword=mysql_real_escape_string($_POST['mypassword']);

// Validate the login
$sql2="SELECT * FROM $tbl_name2 WHERE username='$myusername'";
$result2=mysql_query($sql2);

$row=mysql_fetch_assoc($result2);

//$count=mysql_num_rows($result2);

// If result matched $myusername and $mypassword, table row must be 1 row
//if($count==1)

//$salt = '$2a$18$' . substr(md5(uniqid(rand(), true)), 0, 22);
$encpass = crypt($mypassword, $salt);
if ($encpass == $row['password'])
             {
session_start();             
$_SESSION['myusername'] = $myusername;
header ("Location: memberspage.php");

             }

else {
echo "<center><font color='red'>Invalid Login Details. Not Logged In.</font></center>";
echo "<br>";
echo "<center><font color='red'>Please go back and try again.</font></center>";
echo "<br>";

echo "<center><a href='loginpage.php'>Back</a></center>";
}


}

else {
echo "<center><font color='red'>Wrong Captcha. Not Logged In.</font></center>";
echo "<br>";
echo "<center><font color='red'>Please go back and try again.</font></center>";
echo "<br>";

echo "<center><a href='loginpage.php'>Back</a></center>";
}
?>


<?php 
// close connection 
//mysql_close();
?>

</font>
</html>
<? ob_flush();//Flush buffer output ?>

非常感谢您的帮助。谢谢。


可能是bcrypt和随机生成的盐的重复问题。 - deceze
1
首先,<font face="arial"> 自 1999 年以来就已经过时且非常糟糕。 - Sliq
4
离题了,但是你的代码看起来非常过时...请注意,在HTML中,<center>和<font>标签都已被弃用(应使用CSS),而mysql_xxx() PHP函数也已被弃用(应使用PDO)。 - Spudley
1
而且,“mysql_query”也非常过时。 - Sliq
感谢大家的观察和反馈... 1. 我会尽快使用 CSS 替换已弃用的标签,2. 我正在学习 PDO 并会尽快应用它,3. 一旦我的主机支持 PHP 的内置 password_hash() 函数(尝试过但出现“未定义函数”错误),我也会尽快应用它。谢谢。 - adeoba
3个回答

7
我建议使用PHP内置的password_xxx()函数。这些函数明确设计用于便于使用使用bcrypt哈希加密过的密码。您只需调用password_verify()以检查登录尝试,以及当创建帐户时调用password_hash()即可。简单易用。
这是PHP中处理密码的最简单方法。
请注意,这些函数仅在最新的PHP版本(v5.5)中提供。但是,您可以下载一个向后兼容库,使它们在所有当前支持的PHP版本中(即v5.3和5.4)完全相同。
希望这能有所帮助。

1
password_compat 库适用于 PHP 版本 >= 5.3.7。 - Carlos Campderrós
对于Java,您可以使用:<code> BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder(); if (bCryptPasswordEncoder.matches(rawPassword, encodedPassword) { ... } <code> - Bruno De Freitas Barros

1
尊敬的您,您的代码存在大量错误、过时的内容和非常不安全的后果。我建议您使用专业、经过测试和干净的登录脚本,而不是继续使用您的代码。
1. $salt = '$2a$18$' . substr(md5(uniqid(rand(), true)), 0, 22);已经过时,无法保证任何安全性。即使加盐,$2a算法也是“弱”的算法。
2. mysql_已经过时,不应再使用。
3. <font face="arial">自1999年以来就已经过时,您的其余代码可能也是那个时代的产物。
因此,建议您查看官方PHP密码兼容库https://github.com/ircmaxell/password_compat并使用性感简单的函数构建您的登录系统。或者使用一个已经建立的登录系统,比如这个https://github.com/panique/php-login

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接