我在获取存储在 mysql 中的密码以匹配使用 salt 的登录密码时遇到问题。
这是我创建密码的代码:
$hash = hash('sha256', $password);
function createSalt()
{
$text = md5(uniqid(rand(), true));
return substr($text, 0, 3);
}
$salt = createSalt();
$password = hash('sha256', $salt . $hash);
这是我登录页面中的代码:
$userData = $result->fetch_array(MYSQL_ASSOC);
$hash = hash('sha256', $password);
$password = hash('sha256', $userData['salt'] . $hash);
//$hash = hash('sha256', $userData['salt'] . hash('sha256', $password) );
if($password != $userData['Password']) // Incorrect password. So, redirect to login_form again.
在 mysql 中创建密码时没有错误(该字段填充为 即 0d02a88c1e1057a64df6b3fed4c6ad64e228313b803e9f9b36...
登录名创建类似以下内容:51839f9a15dac1f26825f4cd5d2ecf7ae83ea88d440415b04fb6ae41c3a0566f
只是不确定问题出在哪里。提前感谢,我对PHP很陌生。
首先,这里有一些令人困惑的变量命名 - 你用$password来表示明文密码和盐和散列表示。这使得阅读代码变得更加困难。
其次,让我们将您的代码视为一系列状态,以找出它们可能出错的地方:
- 密码输入。在这两种情况下传递相同的字符串吗?您是否注意空格和大写?使用调试器进行验证。如果明文密码不是逐字节相同的,则初始 sha256 哈希此时应显示差异。
- 盐的生成/回收。您是否逐字节保存/检索了完全相同的盐?同样,注意空格/大写,并检查数据库是否未静默截断或更改字符串的编码。 在字符串连接
- 之后但在第二个 sha256 哈希操作之前比较字符串。根据定义,由于最终输出不同,因此您的明文密码或盐不是逐字节相同的。这将帮助您判断其中一个还是两个都是罪魁祸首。
使用函数 password_hash() 让您的生活更轻松,更安全地存储您的密码。
SHA-* 算法不适合散列密码,因为它们太快了。函数 password_hash() 不仅会计算出更适合的 BCrypt 哈希,还会负责生成安全盐,并且您不必在单独的数据库字段中存储/检索盐(它将成为结果哈希值的一部分)。
// Hash a new password for storing in the database.
// The function automatically generates a cryptographically safe salt.
$hashToStoreInDb = password_hash($password, PASSWORD_BCRYPT);
// Check if the hash of the entered login password, matches the stored hash.
// The salt and the cost factor will be extracted from $existingHashFromDb.
$isPasswordCorrect = password_verify($password, $existingHashFromDb);