如何为哈希函数选择一个盐来保护密码?

时间:2010-09-23 21:04:31

标签: security encryption hash

我是(接近完整的)初学者,这是我第一次涉及加密 - 实际上这可能是我第一次使用这个词。

以下是我的问题:对于非银行/军事,甚至商业网络应用,选择用于密码的哈希函数的盐的正确方法是什么?

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

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

以下任何一种都是好的&实用的想法:

  1. 将盐存储在一个单独的数据库中 - 可能是一个单独的系统,绝对是一个不同的主机,名称,pw等。
  2. 根据用户名(或第一个+姓氏或注册日期)的哈希值生成salt,可能是使用不同的哈希函数?然后盐本身不会存储在数据库中 - 只有用于计算它的数据才会...
  3. 以非显而易见的方式在db中存储将散列的pw和盐连接起来的值(例如,盐是10个随机密钥,并且它们被注入字母编号1和2,4和4之间的散列pw内部。 5,8& 9等)。
  4. 作为一个附带问题,在升级网站软件时更改盐渍哈希算法有多容易?现在感觉很噩梦。

3 个答案:

答案 0 :(得分:9)

  1. 更难以检查密码 - 不推荐。
  2. 最好只生成一个随机数(64位很可能)。
  3. 见(部分)SO 1191112。盐不一定要保密;它必须是不同的。
  4. 回答您的问题:还要存储算法ID(可能是简单的数字,可能是名称字符串)以及数据。升级时,使用新的首选算法对新密码进行哈希处理,但保留旧算法,直到每个人都更改了密码,并且没有使用旧算法存储的密码。同样,这不一定是秘密 - 它只是让你适应世界的变化。很明显,如果旧算法突然暴露为毫无价值,那么您可以考虑使用增量方法是否可行。但除非发生类似这样的戏剧性事件,否则新机制的逐步实施效果非常好。尽量不要经常更改您的算法,以便您一次有三个或更多算法 - 尽管没有技术原因该方案无法管理它。还尝试设计数据库,以便散列大小可以增长而不会导致破坏(因此允许扩展空间从64到128字节,或从128到256,或......)。

答案 1 :(得分:7)

是的,盐只是为了防止彩虹攻击哈希密码。通常我对所有密码使用单个salt值。它存储在我的源代码或配置中,因此它不在数据库中。但是为每个用户使用不同的盐可能更好。这样,具有相同密码的两个用户将无法获得相同的哈希值。

您只需将salt与密码一起存储在数据库中即可。盐的对象是你无法预先计算彩虹表。这需要太多时间。比简单地直接强制密码更多的时间。即使已知盐,也必须生成该盐的完整彩虹表,这样做非常昂贵。因此,如果已知盐则无关紧要。

只要你确保它足够长,你选择盐的方式并不重要。根据维基百科,一个12位哈希(旧的unix密码使用)是非常昂贵的失败,但可能。在可预见的未来,128位(如MD5所使用的)太昂贵了。

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

答案 2 :(得分:4)

盐不是秘密。它们可以与散列的盐+密码一起以明文形式存储。哈希被盐腌以避免字典攻击。使用与密码一起存储的随机值进行腌制或使用用户名和密码进行哈希处理都是有效选项。但是,我建议使用非常特定的哈希方案,即HTTP Digest HA1哈希:user_name : realm : password。这样做的另一个好处是能够验证HTTP摘要调用,这是用于自动访问的身份验证,例如您站点的REST编程API。

在一次跳转以谴责使用MD5而不是SHA1(根据HTTP Digest方案哈希的要求)之前,但在可预见的未来,为摘要方案提供按需MD5哈希冲突仍然远远不可行,并且自动访问的附加好处(想想WebRequest,curl等)不容忽视。