我是在数据库上存储密码的新手,根据我阅读的内容,我在下面创建了一个简单的 php 脚本
<?php
$salt = openssl_random_pseudo_bytes (16);
$password = "test";
$hash = hash ("sha512" , $salt . $password);
echo $hash;
?>
- 我这样做正确吗?
- 盐应该作为字节数据类型存储在数据库中吗?
- 最终的哈希是否应该存储在数据库中的 String 数据类型中?
我是在数据库上存储密码的新手,根据我阅读的内容,我在下面创建了一个简单的 php 脚本
<?php
$salt = openssl_random_pseudo_bytes (16);
$password = "test";
$hash = hash ("sha512" , $salt . $password);
echo $hash;
?>
SHA* 算法不适合散列密码,因为它们的速度太快,因此可能会被暴力破解太快。相反,应该使用一种慢速算法,如 BCrypt 或 PBKDF2,其成本因素控制必要的时间。
PHP 通过新函数password_hash()支持 BCrypt 算法。还有一个适用于早期 PHP 版本的兼容性包。
// 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);
建议您不要传递自己的 salt,而是让函数从操作系统的随机源创建一个加密安全的 salt。
salt 将包含在生成的哈希值中,因此您不必单独存储它。只需在您的数据库中创建一个 60 字符的字符串字段并存储哈希值。该函数password_verify()
将从存储的哈希值中提取使用过的盐。有关更多信息,您可以查看我的关于存储密码的教程。
如果您正在运行,(PHP 5 >= 5.5.0)
那么您可以利用内置的 php 密码散列功能。
简单用法:
$options = [
'cost' => 11,
'salt' => mcrypt_create_iv(22, MCRYPT_DEV_URANDOM), // or your own salt here
];
$pass_hash = password_hash("helloworld", PASSWORD_BCRYPT, $options);
if (password_verify('helloworld', $pass_hash)) {
echo 'Password is valid!';
} else {
echo 'Invalid password.';
}
通常我用散列密码存储盐。我有自己的格式来识别哈希密码的盐。例如,哈希密码为 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824,salt 为 aaabbb。我将盐添加到散列密码,如 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824aaabbb。所以我可以识别出这个散列密码的最后 6 个单词是 salt。即使数据库被黑了,他们仍然不知道盐和真正的密码。