我不太明白盐对密码的作用。据我所知,它的主要用途是阻止彩虹桌的攻击。然而,我所看到的实现这一点的方法似乎并没有真正使问题变得更难。

我看过很多教程,建议盐可以这样使用:

$hash =  md5($salt.$password)

原因是哈希现在映射的不是原来的密码,而是密码和盐的组合。但是输入$salt=foo和$password=bar和$hash=3858f62230ac3c915f300c664312c63f。现在有一张彩虹表的人可以反向哈希,得到输入“foobar”。然后他们可以尝试所有的密码组合(f, fo, foo,…)Oobar, obar, bar, ar)获取密码可能还需要几毫秒的时间,但仅此而已。

我看到的另一种用法是在我的linux系统上。在/etc/shadow中,散列密码实际上与salt一起存储。例如,salt为“foo”,password为“bar”将哈希为$1$foo$te5SBM.7C25fFDu6bIRbX1。如果黑客以某种方式获得了这个文件,我不知道盐有什么用途,因为te5SBM的反向哈希。已知7C25fFDu6bIRbX包含“foo”。

感谢大家对这件事的解释。

编辑:谢谢你的帮助。总结一下我的理解,salt使散列密码更加复杂,从而使它不太可能存在于预先计算的彩虹表中。我之前误解的是,我假设所有哈希表都存在一个彩虹表。


当前回答

我假设您正在使用PHP——md5()函数和$前面的变量——那么,您可以尝试查看本文的影子密码HOWTO特别是第11段。

另外,如果您害怕使用消息摘要算法,则可以尝试真正的密码算法,例如mcrypt模块提供的算法,或者更强大的消息摘要算法,例如提供mhash模块的算法(sha1、sha256等)。

我认为更强的消息摘要算法是必须的。已知MD5和SHA1存在冲突问题。

其他回答

当破解单个密码时,公共盐不会使字典攻击更加困难。正如您所指出的,攻击者可以访问散列密码和salt,因此在运行字典攻击时,她可以在试图破解密码时简单地使用已知的salt。

公共盐做了两件事:使破解大量密码列表更加耗时,并使使用彩虹表变得不可行的。

To understand the first one, imagine a single password file that contains hundreds of usernames and passwords. Without a salt, I could compute "md5(attempt[0])", and then scan through the file to see if that hash shows up anywhere. If salts are present, then I have to compute "md5(salt[a] . attempt[0])", compare against entry A, then "md5(salt[b] . attempt[0])", compare against entry B, etc. Now I have n times as much work to do, where n is the number of usernames and passwords contained in the file.

To understand the second one, you have to understand what a rainbow table is. A rainbow table is a large list of pre-computed hashes for commonly-used passwords. Imagine again the password file without salts. All I have to do is go through each line of the file, pull out the hashed password, and look it up in the rainbow table. I never have to compute a single hash. If the look-up is considerably faster than the hash function (which it probably is), this will considerably speed up cracking the file.

但是如果密码文件被加了盐,那么彩虹表就必须包含“salt”。pre-hashed密码”。如果盐是完全随机的,这是不太可能的。在我的常用预哈希密码列表(彩虹表)中,我可能会有“hello”、“foobar”和“qwerty”这样的东西,但我不会预先计算“jX95psDZhello”或“LPgB0sdgxfoobar”或“dZVUABJtqwerty”这样的东西。这将使彩虹桌大得令人望而却步。

因此,salt将攻击者减少到每行每次尝试一次计算,当加上足够长、足够随机的密码时,(一般来说)是不可破解的。

我假设您正在使用PHP——md5()函数和$前面的变量——那么,您可以尝试查看本文的影子密码HOWTO特别是第11段。

另外,如果您害怕使用消息摘要算法,则可以尝试真正的密码算法,例如mcrypt模块提供的算法,或者更强大的消息摘要算法,例如提供mhash模块的算法(sha1、sha256等)。

我认为更强的消息摘要算法是必须的。已知MD5和SHA1存在冲突问题。

盐会导致彩虹表攻击失败的原因是,对于n位盐,彩虹表必须比没有盐的表大2^n倍。

你使用“foo”作为盐的例子可以使彩虹表变大1600万倍。

以卡尔的128位盐为例,这使表变大了2^128倍,这很大了,换句话说,要多久才会有人有这么大的便携式存储器?

我正在寻找一个好的方法来应用盐,发现这篇优秀的文章与示例代码:

http://crackstation.net/hashing-security.htm

作者建议对每个用户使用随机salt,这样访问salt就不会使整个哈希列表容易被破解。

To Store a Password: Generate a long random salt using a CSPRNG. Prepend the salt to the password and hash it with a standard cryptographic hash function such as SHA256. Save both the salt and the hash in the user's database record. To Validate a Password : Retrieve the user's salt and hash from the database. Prepend the salt to the given password and hash it using the same hash function. Compare the hash of the given password with the hash from the database. If they match, the password is correct. Otherwise, the password is incorrect.

据我所知,盐是为了使字典攻击更加困难。

众所周知,许多人会使用常见的单词作为密码,而不是看似随机的字符串。

因此,黑客可以利用这一点,而不是仅仅使用蛮力。他不会找像aaa, aab, aac这样的密码……而是使用单词和常用的密码(比如指环王的名字!,))

所以如果我的密码是Legolas,黑客可以尝试一下,并通过“几次”尝试来猜测它。但是,如果我们对密码加盐,它就变成了fooLegolas,哈希值就会不同,所以字典攻击就会不成功。

希望有帮助!