【问题标题】:Correct way of using SHA512 encryption使用SHA512加密的正确方法
【发布时间】:2015-01-27 13:01:15
【问题描述】:

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

我的盐:

$salt = base64_encode(substr(str_shuffle("./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345‌​6789"), 0, 12));

我得到这样的东西:

Q4CALzJNenFaZnNK

我不确定为什么我指定 12 时长度为 16。

为了散列密码,我使用这个:

$hashed = crypt('myPassword', '$6$rounds=5000000$'.$salt);

输出是这样的:

$6$rounds=5000000$Q4CALzJNenFaZnNK$9QTP6C.BZ9Z.U85UIEAVX1dEIdShHFoYGgTMvgv9Cx/XZY1mK/n2rY4FuHSoigjgIXfqGZftZSxrrF.cDBzt8/

长度:121

所以我的问题是可以将此密码存储在数据库中,还是应该像我在几个示例中看到的那样去掉 $ 符号?

此外,我已经将密码存储在 VARCHAR(255) 中,我想知道是否可以使输出的长度增加一倍,即接近 255 个字符?

这种方式比 Blowfish 更安全吗?


我的发现:

哈希密码的长度并不像我最初想象的那么重要(60 个字符足以存储而不是 128 或 256)。

最好使用 password_hash 函数,忘记生成自己的 salt - php.net 知道他们在做什么。

所以我最终以这种方式散列密码:

$hash = password_hash($password, PASSWORD_BCRYPT, array("cost"=>15));

PASSWORD_BCRYPT 是 Blowfish 算法,默认成本为 10(运行算法或其他东西的时间)。 10 是减缓蛮力攻击的好数字。我想展示如何手动更改成本。

【问题讨论】:

  • (SHA512 不是加密,它的散列)Base64 编码长度为 X 的东西并不能保证输出长度为 X;输出将始终更长。您将从 base64 输出中获取 12 - 或者更好地生成一个真正的随机值,该值不基于具有未知随机性的一小部分字节。
  • “如果我可以将输出时间延长一倍” - 为什么?它不会更安全。它将需要更多存储空间。
  • PHP 有password_hash(),它可以为你处理加盐和一切。不要重新发明轮子。
  • 您创建盐的方法并不安全。它只会使用每个字母一次,并且它永远不会创建字符串 AAABBB 例如。最好使用 PHP 内置的盐生成算法,例如使用password_hash
  • 将 password_hash() 与 SHA512 一起使用的正确方法是什么?我尝试使用 $hash = password_hash('myPassword', CRYPT_SHA512);但它可疑地返回了 Blowfish(默认)算法:$2y$10$dyKVDUfXTBrHiGtHESjn7udXsTjzcsJ26oE5uU9IEA3Vdo6VrRBWK

标签: php security passwords sha512


【解决方案1】:
  1. 因为 base64_encode 会将你的 12 个字符的字符串放大为 16 个字符的字符串(它的编码就是这样做的),所以你会得到一个更大的盐。
  2. 您可以将字符串完全存储在一个字段中,但如果您想轻松访问盐,您可以将盐存储在另一个字段中。 (您需要再次使用 salt 来重新检查用户密码输入是否正确 - salt 仅确保相同密码的哈希不会给出相同的哈希)
  3. SHA512 是否比 Blowfish 更安全?正如erickson on stackoverflow 所说,它们都足以达到目的

【讨论】:

    【解决方案2】:

    你有这个:

    $salt = base64_encode(substr(str_shuffle("./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"), 0, 12));
    

    您可以简单地从中删除 base64_encode 以获得 12 个字符的盐。另请注意,在您的版本中,您在 5 和 6 之间有一些非 ascii、不可打印的字符。这可能会导致二进制输出。试试这个:

    $salt = substr(str_shuffle("./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"), 0, 12);
    

    【讨论】:

      【解决方案3】:

      所以我的问题是可以将此密码存储在数据库中

      是的,只需将整个内容存储在数据库中,包括$6$rounds=5000000。这使得将来可以切换到另一种哈希类型,您可以在整个密码上使用crypt来检查它。

      【讨论】:

        【解决方案4】:

        此外,我已经将密码存储在 VARCHAR(255) 中,我想知道是否可以使输出的长度增加一倍,即接近 255 个字符?

        原则上越长越好,所以 SHA512 优于 SHA256。然而,一个 120 个字符的散列已经很长了,再长一点也没好处。您可以增加盐的长度,但不要试图通过附加另一个哈希或类似的东西来使哈希更长。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-11-21
          • 2012-11-18
          • 2011-11-18
          • 2015-06-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多