【问题标题】:How to choose a salt for a hash function meant to protect passwords?如何为旨在保护密码的哈希函数选择盐?
【发布时间】:2011-04-16 12:00:55
【问题描述】:

我是一个(接近完整的)初学者,这是我第一次涉足加密领域——事实上这可能是我第一次使用这个词。

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

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

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

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

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

作为一个附带问题,在升级网站软件时更改加盐哈希算法有多容易?现在感觉就像噩梦一样。

【问题讨论】:

  • 谢谢。没有解决 1、2 和 3 - 还是我遗漏了什么?
  • 关于这方面的信息很多。简而言之:使用每个用户的盐,对盐使用随机数据,不要担心“保护”盐,因为它们本身并不是秘密的。
  • 如果您碰巧在数据库中为用户使用了 GUID id;这可以作为盐字节的绝佳来源。
  • @DanP - 非常好的意见,谢谢。

标签: security encryption hash


【解决方案1】:
  1. 使检查密码更加困难 - 不推荐。
  2. 最好只生成一个随机数(64 位可能就足够了)。
  3. 请参阅(部分)SO 1191112。盐不必保密;它必须与众不同。

回答您的附带问题:还存储一个算法 ID(可能是一个简单的数字,可能是一个名称字符串)以及数据。升级时,您使用新的首选算法散列新密码,但您保留旧算法,直到每个人都更改了密码并且没有使用旧算法存储的密码。同样,这不必保密 - 它只是让您适应世界的变化。显然,如果旧算法突然被暴露为一文不值,您会考虑使用增量方法是否可以。但除非发生类似的戏剧性事件,否则逐步采用新机制效果很好。尽量不要频繁更改您的算法,以至于您一次有三个或更多在旅途中 - 尽管没有技术原因该方案无法管理它。还可以尝试设计您的数据库,以便哈希大小可以增长而不会引起破坏(因此允许从 64 字节扩展到 128 字节,或从 128 字节扩展到 256 字节,或者......)。

【讨论】:

    【解决方案2】:

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

    您可以简单地将盐与密码一起存储在数据库中。盐的目的是你不能预先计算彩虹表。这将花费太多时间。比简单地直接暴力破解密码更多时间。即使知道盐,也必须生成该盐的完整彩虹表,这非常昂贵。所以,盐是否已知并不重要。

    只要确保盐足够长,如何挑选盐并不重要。根据 Wikipedia 的说法,12 位散列(旧的 unix 密码使用)的破解成本非常高,但有可能。在可预见的未来,128 位(如 MD5 所使用的)过于昂贵而无法取消。

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

    【讨论】:

    • 为每个用户使用不同的盐肯定更好。否则,您可以发现两个用户共享相同密码的情况。
    • 好的 - 大概你可以有 24 个预先计算的盐,并为名称的每个第一个字母使用不同的盐,等等。但我从你那里得到的是,你已经得到了 90%使用任何随机的长盐的好处——即使它是已知的。
    【解决方案3】:

    盐不是秘密。它们可以与散列盐+密码一起清晰地存储。散列被加盐以避免字典攻击。使用与密码一起存储的随机值进行加盐或将用户名与密码一起散列都是有效的选项。但是,我会推荐一个非常特定的哈希方案,即 HTTP Digest HA1 哈希:user_name : realm : password。这还有一个额外的好处,就是能够对 HTTP Digest 调用进行身份验证,这就是用于自动访问的身份验证,就像您网站的 REST 编程 API。

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

    【讨论】:

    • 将用户名作为散列算法的一部分的缺点是用户无法更新其用户名,而无需重置密码。由于电子邮件地址通常是用户名的替代品,因此这可能会出现 UI 问题。最好将盐简单地存储在数据库中并完成。
    • 鉴于这些规定的约束,用户 ID(通常是 0-10000 之间的整数)不能用作 Salt 值吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-06
    • 1970-01-01
    • 2012-06-12
    • 2015-10-24
    • 2015-05-27
    • 2012-11-04
    • 1970-01-01
    相关资源
    最近更新 更多