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

19

我是一个(近乎完全的)初学者,这是我第一次尝试加密 - 实际上,这可能是我第一次使用这个词。

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

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

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

以下哪些想法是好的和实用的:

  1. 将盐存储在单独的数据库中-可能是单独的系统,绝对是不同的主机,名称,密码等。
  2. 基于用户名(或名字+姓氏,或注册日期)的哈希值生成盐,可能使用不同的哈希函数? 然后盐本身不会存储在数据库中-仅用于计算它的数据...
  3. 在数据库中存储一个将哈希密码和盐连接起来的值,以一种不明显的方式(例如,盐是10个随机密钥,并且它们被注入在哈希密码中的字母数字1和2、4和5、8和9之间等)。

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


2
重复:https://dev59.com/EnM_5IYBdhLWcg3w3nVs - tangens
谢谢。这并没有解决1、2和3,或者我漏看了什么? - JDelage
1
关于这个问题已经有很多信息了。简而言之:使用每个用户的盐,使用随机数据作为盐,并不必担心“保护”盐,因为它们并不是绝对机密的。 - snemarch
2
如果你在数据库中使用GUID ID作为用户ID,这可以作为盐值字节的绝佳来源。 - DanP
3个回答

11
  1. 使密码检查更加困难,不建议使用。
  2. 最好只是生成一个随机数(64位可能已经足够)。
  3. 请参阅(部分内容)SO 1191112。盐不必保密,只需保证不同即可。

回答您的附加问题:还要将算法ID(可能是简单数字,也可能是名称字符串)与数据一起存储。随着升级,您会使用新的首选算法对新密码进行哈希处理,但在所有人都更改密码且没有存储使用旧算法的密码之前,您会保留旧算法。再次强调,这不必保密-它只允许您适应世界的变化。显然,如果旧算法突然被暴露为毫无价值,您需要考虑是否可以使用增量方法。但除非发生像那样的剧烈情况,否则逐步引入新的机制效果很好。尽量不要更改算法,以至于您同时进行三个或更多算法-尽管技术上方案可以管理它。还要设计数据库,使哈希大小可以增长而不会造成骚动(因此允许从64个字节扩展到128个字节,或从128个字节扩展到256个字节,或...)。


9
是的,盐值只是为了防止散列密码遭受彩虹攻击。通常我会为所有密码使用单个盐值。它存储在我的源代码或配置中,因此不存储在数据库中。但最好为每个用户使用不同的盐值,这样具有相同密码的两个用户将不会得到相同的哈希值。
您可以将盐值与密码一起存储在数据库中。盐的目标是防止预计算彩虹表。这需要耗费太多时间。比直接暴力破解密码要花费更多时间。即使知道盐值,也必须生成该盐值的完整彩虹表,这非常昂贵。因此,如果已知盐值,这并不重要。
挑选盐的方法并不重要,只要确保足够长即可。根据维基百科的说法,12位哈希(用于旧版Unix密码)非常难以打败,但有可能。128位(例如MD5使用的位数)在可预见的未来内无法被打败。
参见:http://en.wikipedia.org/wiki/Rainbow_table#Defense_against_rainbow_tables

8
最好为每个用户使用不同的盐。否则,当两个用户共享相同的密码时,你就可以发现它们。 - Jonathan Leffler
好的 - 可能你不只有一个而是24个预先计算的盐,并且对于每个名称的第一个字母使用不同的盐。但是我从你这里得到的是,即使已知,使用任意随机的长盐也可以获得90%的好处。 - JDelage

4

盐并不是秘密。它们可以与哈希的盐+密码一起明文存储。为了避免字典攻击,哈希被加盐处理。使用随机值与密码一起存储或将用户名与密码进行哈希处理都是有效的选项。但是,我建议使用一个非常具体的哈希方案,即HTTP 摘要HA1哈希:user_name:realm:password。这有一个额外的好处,即能够验证HTTP Digest调用,这就是认证将用于自动化访问,例如您网站的REST编程API。

在谴责使用MD5而不是SHA1之前(如HTTP摘要方案哈希所需),但提供按需MD5哈希冲突仍远未实现,而自动访问的附加好处(考虑WebRequest、curl等)也不容忽视。


6
将用户名作为哈希算法的一部分有一个缺点,那就是用户在更新用户名时必须同时重置密码。由于电子邮件地址通常代替用户名,这可能会导致用户界面问题。最好的方法是仅将盐存储在数据库中,然后结束它。 - David
2
考虑到这些限制条件,用户ID(通常为0-10000之间的整数)可以用作盐值吗? - Black

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接