我有一个允许用户插入密码的注册页面。我在注册时对密码进行哈希,以便更安全地存储在数据库中。
当用户使用相同的密码登录时,两个哈希值不匹配,用户无法登录。
这是我第一次使用哈希,它的行为不像我预期的那样:
这是注册页面上的哈希代码:
$salt ="";
function cryptPass($input, $rounds = 9)
{
$salt = "";
$saltChars = array_merge(range('A','Z'), range('a','z'), range('0','9'));
for($i = 0; $i<22; $i++)
{
$salt .=$saltChars[array_rand($saltChars)];
}
return crypt($input, sprintf('$2y$%02d$test$', $rounds) . $salt);
}
$hashedpass = cryptPass($pass1);
echo $hashedpass;
//************Insert all the members's input to the database**************************//
$query = mysql_query("INSERT INTO members(user_name, first_name, last_name, governorate, district, village, birth_date, email_address, specialization, password, salt, registered_date )VALUES('$username', '$firstname', '$lastname', '$governorate', '$district', '$village', '$bdate', '$email', '$specialization', '$hashedpass', '$salt', now())")or die(mysql_error());
我确实加了盐,但它是空的
这是登录页面上的哈希代码
function cryptPass($input, $rounds = 9)
{
$salt = "";
$saltChars = array_merge(range('A','Z'), range('a','z'), range('0','9'));
for($i = 0; $i<22; $i++)
{
$salt .=$saltChars[array_rand($saltChars)];
}
return crypt($input, sprintf('$2y$%02d$test$', $rounds) . $salt);
}
$hashedpass = cryptPass($pass);
echo $hashedpass;
$sql=mysql_query( "SELECT user_id, email_address, first_name, user_name FROM members WHERE email_address='$email'AND password= '$hashedpass' LIMIT 1") or die("error in members table");
$login_check = mysql_num_rows($sql);
if($login_check > 0)the hashing password = $2y$09$test$4ZGgCiXdKzgQvuzwu.AxfdWvZadDCE.LD6HCkrK3ZsqJeN7e
当用户注册时,您需要在数据库中存储盐和散列密码。当用户尝试登录时,您需要使用与他们注册时相同的盐,否则哈希将不同。这被称为每个用户的盐,是更安全的选择。
一个更简单但不太安全的选择是为应用程序生成单个盐值,并将其用于所有用户。这将使所有密码在数据库中保持散列,但安全性要低得多,因为如果盐值被破坏,那么暴力破解散列密码是一件微不足道的事情。
您需要在数据库中存储盐,以及散列密码。
当用户尝试登录时,您需要从数据库中获取盐,并使用它对用户输入进行哈希,以便将其与哈希后的密码进行比较。
在您的示例中,您将在登录过程中生成一个随机盐,该盐永远不会生成与数据库中相同的哈希值。
如果您要自己编写它,则需要将生成的盐存储在DB中(正如其他响应者所说)。更一般地说,我会尝试尽可能多地委托给提供开箱即用密码支持的外部库。获得正确的加密是很难的,在你开始自己滚动之前,你真的需要多读一点。有很好的库支持。你应该用它。
另外,您真的不应该使用MD5来散列密码。使用bcrypt、pbkdf2或其他适合密码的散列。
密码盐渍的工作原理是在散列之前向密码添加预定义的随机明文集。这避免了两个选择相同密码的用户产生两个相同的哈希值。假设系统中的两个用户user1和user2选择'letmein'作为密码:
salt_user1 = 'awoidjalskdm'
hash = MD5('letmein'+salt_user1) = ab82a9c495e3fe88d1986176e4850b1d
和user2
salt_user2 = 'duiesnblekfn'
hash = MD5('letmein'+salt_user2) = 69caac44b5ee9f8b6468b5625000723a
假设您的数据库结构类似于username:salt:password_hash,那么您将得到:
user1:awoidjalskdm:ab82a9c495e3fe88d1986176e4850b1d
user2:duiesnblekfn:69caac44b5ee9f8b6468b5625000723a
密码盐的主要目的是避免大量的密码泄露,如果您的数据库被泄露。密码盐将使暴力破解由几个不同用户选择的简单和流行密码变得更加困难。
在您的情况中,似乎您正在随机生成用于注册的盐(这很好)。错误似乎是在登录功能,在那里你重新计算一个随机的盐,而不是检索一个已经生成的早期,应该已经存储。
在对密码进行散列之前附加的盐需要对每个用户都是相同的,并且需要能够在需要时调用它。尽管看起来有些矛盾,但这意味着它必须以明文形式存储在数据库中。