【问题标题】:Password hashing and salting密码散列和加盐
【发布时间】:2015-02-17 12:11:50
【问题描述】:

我正在尝试用 MD5/SHA 结合加盐来加密密码的逻辑。

我理解用户证明文本密码的概念,并将随机字符串(盐)附加到文本密码,并通过您想要的任何加密方法对最终字符串进行哈希处理。

这就是我失去概念的地方

假设在我的用户数据库中,我有用户名和使用随机盐值生成的加密密码

当用户登录系统并输入密码时,我如何获取正确的盐来检查密码的有效性?

如果盐是随机生成的,我无法重新计算它

我必须将盐与用户名/密码记录一起存储吗?如果我通过用户名在数据库中查询盐值,这似乎违背了盐化的目的。

在验证提供的密码时如何获得正确的盐?

【问题讨论】:

    标签: hash salt


    【解决方案1】:

    来自*,Salt (cryptography)

    为每个密码随机生成一个新盐。在典型的设置中,盐和密码被连接并使用加密哈希函数进行处理,结果输出(但不是原始密码)与盐一起存储在数据库中

    您将其与哈希一起存储,以防止字典攻击。

    【讨论】:

      【解决方案2】:

      盐存储在数据库中,因此您可以使用相同的盐来验证密码。今天的库通常会在生成的哈希值中包含盐,如下所示(PHP 函数password_hash() 的结果):

      $2y$10$nOUIs5kJ7naTuTFkBy1veuK0kSxUFXfuaOKdOKf9xYT0KKIGSJwFa
       |  |  |                     |
       |  |  |                     hash-value = K0kSxUFXfuaOKdOKf9xYT0KKIGSJwFa
       |  |  |
       |  |  salt = nOUIs5kJ7naTuTFkBy1veu (22 characters)
       |  |
       |  cost-factor = 10 = 2^10 iterations
       |
       hash-algorithm = 2y = BCrypt
      

      这 60 个字符的字符串可以存储到数据库中的单个字段中。验证函数可以从这个字符串中提取盐。盐不是秘密,即使知道了,它也能实现它的目的。

      请注意,像 MD5 和 SHA-* 这样的算法适合散列密码,因为它们太快了。而是使用具有成本因子的算法,例如 BCrypt 或 PBKDF2。有关安全存储密码的更多信息,您可以查看我的tutorial

      【讨论】:

        【解决方案3】:

        是的,你储存盐。 Salting 用于防止预生成彩虹表,不需要保密,只是不可预测。

        【讨论】: