SHA512加密的正确使用方法
Correct way of using SHA512 encryption
我正在尝试使用函数 crypt 在 PHP 中使用 SHA512 算法。
我的盐:
$salt = base64_encode(substr(str_shuffle("./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"), 0, 12));
我得到这样的结果:
Q4CALzJNenFaZnNK
我不确定为什么在我指定 12 时得到长度 16。
为了散列密码,我使用这个:
$hashed = crypt('myPassword', '$rounds=5000000$'.$salt);
输出是这样的:
$rounds=5000000$Q4CALzJNenFaZnNKQTP6C.BZ9Z.U85UIEAVX1dEIdShHFoYGgTMvgv9Cx/XZY1mK/n2rY4FuHSoigjgIXfqGZftZSxrrF.cDBzt8/
长度:121
所以我的问题是可以将此密码存储在数据库中,还是应该像我在几个示例中看到的那样去掉 $ 符号?
此外,我已经将密码存储在 VARCHAR(255) 中,我想知道是否可以使输出的长度加倍,即接近 255 个字符?
这种方式比例如 Blowfish 更安全吗?
我的发现:
散列密码的长度并不像我最初想的那么重要(60 个字符足以存储而不是 128 或 256)。
最好使用 password_hash 函数并忘记生成自己的盐 - php.net 知道他们做什么。
所以我最终以这种方式散列密码:
$hash = password_hash($password, PASSWORD_BCRYPT, array("cost"=>15));
PASSWORD_BCRYPT 是 Blowfish 算法,默认成本为 10(运行算法或其他时间)。 10 是减慢蛮力攻击的好数字。我想向您展示如何手动更改费用。
你有这个:
$salt = base64_encode(substr(str_shuffle("./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"), 0, 12));
您只需从中删除 base64_encode
即可获得 12 个字符的盐。另请注意,在您的版本中,5 和 6 之间有一些非 ascii、不可打印的字符。这可能会导致二进制输出。试试这个:
$salt = substr(str_shuffle("./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"), 0, 12);
So my question is it ok to store this password in the database
是的,只需将整个内容存储在数据库中,包括 $
和 rounds=5000000
。这使得将来可以切换到另一种哈希类型,您可以只对整个密码使用 crypt
来检查它。
- 你得到更大的盐,因为 base64_encode 会将你的 12 个字符的字符串扩大到 16 个字符的字符串(它的编码就是这样做的)
- 您可以将字符串完全存储在一个字段中,但如果您想轻松访问盐,则可以将盐存储在另一个字段中。 (您需要再次加盐以重新检查用户密码输入是否正确 - 加盐仅确保相同密码的散列不会给出相同的散列)
- SHA512 和 Blowfish 一样安全吗?正如 erickson on Whosebug 所说,它们都足够好
Also I already store passwords in VARCHAR(255) and I was wondering if I could make the output twice as long, i.e. near 255 characters?
原则上越长越好,所以SHA512比SHA256好。然而,120 个字符的散列已经很长了,再长一点也没有什么好处。您可以增加盐的长度,但不要试图通过附加另一个散列或类似的东西来使散列更长。
我正在尝试使用函数 crypt 在 PHP 中使用 SHA512 算法。
我的盐:
$salt = base64_encode(substr(str_shuffle("./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"), 0, 12));
我得到这样的结果:
Q4CALzJNenFaZnNK
我不确定为什么在我指定 12 时得到长度 16。
为了散列密码,我使用这个:
$hashed = crypt('myPassword', '$rounds=5000000$'.$salt);
输出是这样的:
$rounds=5000000$Q4CALzJNenFaZnNKQTP6C.BZ9Z.U85UIEAVX1dEIdShHFoYGgTMvgv9Cx/XZY1mK/n2rY4FuHSoigjgIXfqGZftZSxrrF.cDBzt8/
长度:121
所以我的问题是可以将此密码存储在数据库中,还是应该像我在几个示例中看到的那样去掉 $ 符号?
此外,我已经将密码存储在 VARCHAR(255) 中,我想知道是否可以使输出的长度加倍,即接近 255 个字符?
这种方式比例如 Blowfish 更安全吗?
我的发现:
散列密码的长度并不像我最初想的那么重要(60 个字符足以存储而不是 128 或 256)。
最好使用 password_hash 函数并忘记生成自己的盐 - php.net 知道他们做什么。
所以我最终以这种方式散列密码:
$hash = password_hash($password, PASSWORD_BCRYPT, array("cost"=>15));
PASSWORD_BCRYPT 是 Blowfish 算法,默认成本为 10(运行算法或其他时间)。 10 是减慢蛮力攻击的好数字。我想向您展示如何手动更改费用。
你有这个:
$salt = base64_encode(substr(str_shuffle("./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"), 0, 12));
您只需从中删除 base64_encode
即可获得 12 个字符的盐。另请注意,在您的版本中,5 和 6 之间有一些非 ascii、不可打印的字符。这可能会导致二进制输出。试试这个:
$salt = substr(str_shuffle("./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"), 0, 12);
So my question is it ok to store this password in the database
是的,只需将整个内容存储在数据库中,包括 $
和 rounds=5000000
。这使得将来可以切换到另一种哈希类型,您可以只对整个密码使用 crypt
来检查它。
- 你得到更大的盐,因为 base64_encode 会将你的 12 个字符的字符串扩大到 16 个字符的字符串(它的编码就是这样做的)
- 您可以将字符串完全存储在一个字段中,但如果您想轻松访问盐,则可以将盐存储在另一个字段中。 (您需要再次加盐以重新检查用户密码输入是否正确 - 加盐仅确保相同密码的散列不会给出相同的散列)
- SHA512 和 Blowfish 一样安全吗?正如 erickson on Whosebug 所说,它们都足够好
Also I already store passwords in VARCHAR(255) and I was wondering if I could make the output twice as long, i.e. near 255 characters?
原则上越长越好,所以SHA512比SHA256好。然而,120 个字符的散列已经很长了,再长一点也没有什么好处。您可以增加盐的长度,但不要试图通过附加另一个散列或类似的东西来使散列更长。