代码之家  ›  专栏  ›  技术社区  ›  JDelage

如何为用于保护密码的哈希函数选择salt?

  •  17
  • JDelage  · 技术社区  · 16 年前

    我的问题是:对于一个非银行/军事,甚至是商业的web应用程序,为用于密码的散列函数选择salt的正确方法是什么?

    我可以轻松地为每个新用户生成一个伪随机salt,并在应用hash函数之前将该salt附加到他们的pw中。但是我仍然需要存储盐,所以可能任何访问散列密码的人也会得到盐。

    salt的好处仅仅是使pw“更随机”,从而击败基于字典的标准彩虹表吗?

    1. 将盐存储在一个单独的数据库中-可能是一个单独的系统,肯定是一个不同的主机、名称、pw等。
    2. 根据用户名(或名字+姓氏,或注册日期)的哈希生成salt,可能使用不同的哈希函数?然后盐本身就不会存储在数据库中-只有用来计算它的数据会。。。
    3. 在db中以不明显的方式(例如,salt是10个随机键,它们被注入哈希pw中的字母数字1&2、4&5、8&9等)存储一个连接哈希pw和salt的值。

    3 回复  |  直到 16 年前
        1
  •  9
  •   Community Mohan Dere    9 年前
    1. 使检查密码更加困难-不推荐。
    2. 见(部分) SO 1191112

    要回答您的附带问题:还要将算法ID(可能是一个简单的数字,可能是一个名称字符串)与数据一起存储。升级时,使用新的首选算法散列新密码,但保留旧算法,直到每个人都更改了密码并且没有使用旧算法存储的密码。再说一次,这不一定是秘密-它只允许你适应世界的变化。显然,如果旧的算法突然暴露为毫无价值,那么您应该考虑使用增量方法是否可行。但除非发生类似戏剧性的事情,否则逐步采用新机制的效果相当不错。尽量不要频繁地更改算法,以至于一次有三个或更多的算法在运行——尽管没有技术上的原因说明方案无法管理它。还要尝试设计您的数据库,以便哈希大小可以增长而不会引起混乱(因此允许从64字节扩展到128字节,或从128字节扩展到256字节,或…)。

        2
  •  8
  •   Sander Marechal    16 年前

    是的,盐只是用来防止对散列密码的彩虹攻击。通常我对所有密码使用一个salt值。它存储在我的源代码或配置中,所以不在数据库中。但对每个用户使用不同的盐可能更好。这样,具有相同密码的两个用户将不会得到相同的哈希值。

    您可以简单地将salt和密码一起存储在数据库中。salt的目标是不能预计算彩虹表。那会花太多时间。更多的时间不只是直接强制输入密码。即使已知盐,也必须生成盐的完整彩虹表,这是非常昂贵的。所以,盐是否已知并不重要。

    你怎么选盐并不重要,只要你确定它足够长。根据维基百科(Wikipedia)的说法,12位散列(旧unix密码使用的)非常昂贵,但可能会失败。128位(如MD5所使用的)在可预见的将来太昂贵而无法消除。

    另请参见: http://en.wikipedia.org/wiki/Rainbow_table#Defense_against_rainbow_tables

        3
  •  4
  •   Remus Rusanu    16 年前

    盐不是秘密。它们可以与散列的salt+密码一起以明文形式存储。散列被咸化以避免字典攻击。将随机值与密码一起存储或将用户名与密码一起散列都是有效的选项。不过,我还是建议 哈希方案,即HTTP Digest HA1 user_name : realm : password . 这还有一个额外的好处,那就是能够对HTTP摘要调用进行身份验证,而这正是身份验证的用途 访问,就像站点的REST编程API。

    在人们开始谴责使用MD5而不是SHA1之前(按照HTTP摘要方案散列的要求),但是为摘要方案提供按需MD5散列冲突在可预见的将来仍然是不可行的,并且自动访问的附加好处(比如WebRequest、curl等)也不容忽视。