SHA512加密的正确使用方法

Correct way of using SHA512 encryption

我正在尝试使用函数 crypt 在 PHP 中使用 SHA512 算法。

我的盐:

$salt = base64_encode(substr(str_shuffle("./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345‌​6789"), 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 来检查它。

  1. 你得到更大的盐,因为 base64_encode 会将你的 12 个字符的字符串扩大到 16 个字符的字符串(它的编码就是这样做的)
  2. 您可以将字符串完全存储在一个字段中,但如果您想轻松访问盐,则可以将盐存储在另一个字段中。 (您需要再次加盐以重新检查用户密码输入是否正确 - 加盐仅确保相同密码的散列不会给出相同的散列)
  3. 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 个字符的散列已经很长了,再长一点也没有什么好处。您可以增加盐的长度,但不要试图通过附加另一个散列或类似的东西来使散列更长。