在为数据库存储散列密码时,我总是使用适当的每项salt字符串。对于我的需要,在DB中将盐存储在散列密码旁边总是很好。

然而,有些人建议将盐与数据库分开存储。他们的论点是,如果数据库被破坏,攻击者仍然可以构建一个彩虹表,将特定的盐字符串考虑在内,以便一次破解一个帐户。如果这个帐户有管理权限,那么他甚至不需要破解任何其他帐户。

从安全的角度来看,把盐存放在不同的地方值得吗?考虑一个web应用程序,其服务器代码和DB位于同一台机器上。如果salt存储在该机器上的平面文件中,那么如果数据库受到威胁,那么盐类文件也会受到威胁。

对此有什么建议的解决方案吗?


当前回答

彩虹表的重点是,它们是预先创建的,并大量分布,以节省其他人的计算时间——实时生成彩虹表所需的时间与直接破解密码+salt组合所需的时间一样长(因为在生成彩虹表时,实际上所做的是预先运行计算以进行野蛮强制哈希),因此,通过知道盐就可以“生成彩虹表”的说法是虚假的。

在单独的文件中存储salt没有实际意义,只要它们是基于每个用户的——salt的意义只是为了使一个彩虹表不能破坏数据库中的每个密码。

其他回答

如果您使用的库(或自己创建的库)使用固定大小的字符串作为salt,那么您可以将salt和散列密码存储在同一个字段中。然后拆分存储的值以检索盐和散列密码以验证输入。

使用10个字符的salt和固定的40个字符的散列大小,它看起来像这样:

salt = "california"
passwd = "wp8tJ4Pr"

stored_passwd = salt + hash(passwd + salt)

salt = substr(stored_passwd, 0, 10)
hashed_passwd = substr(stored_passwd, 10, 40)

if hash(user_input + salt) == hashed_passwd:
    print "password is verified"

由于salt的全部目的是防止使用预先计算的表(例如彩虹表)进行密码攻击,因此将salt与散列密码一起存储实际上是无害的。

通常,它们被前置到散列中并存储在相同的字段中。

没有必要单独存储它们——关键是为每个密码使用随机盐,这样单个彩虹表就不能用于整个密码哈希集。对于随机盐,攻击者必须单独强行执行每个哈希(或者为所有可能的盐计算一个彩虹表——工作量大得多)。

如果您有一个更安全的存储位置,那么只将哈希存储在那里是有意义的。

The point of a salt is to render all rainbow tables useless and require a new set of them to be made. It takes just as long to guess a string as to make a rainbow table. For example the SHA-256 hash of "password" is 5e88 4898 da28 0471 51d0 e56f 8dc6 2927 7360 3d0d 6aab bdd6 2a11 ef72 1d15 42d8. After a salt is added, such as "badpassword" the new string to be hashed is "passwordbadpassword" which, due to the avalanche effect, dramatically changes the output, to 457b f8b5 37f1 802e f9c8 2e46 b8d3 f8b5 721b 7cbb d485 f0bb e523 bfbe 73e6 58d6.

通常情况下,盐只存储在与密码相同的数据库中,这也是因为如果一个数据库被黑客入侵,另一个数据库也很可能会被黑客入侵。

基于ASP的开发。NET MVC 4 Web应用程序的书由William Penberthy:

Getting access to the salts stored in a separate database requires hackers to hack two different databases to get access to the salt and the salted password. Storing them in the same table as the password, or even another table of the same database, would mean that when hackers gain access to the database, they will have access to both the salt and the password hash. Because security includes the process of making hacking into the system too expensive or time-consuming to be worth it, doubling the amount of access a hacker would have to gain should make the system more secure. Ease of use is the primary reason for keeping the salts in the same database as the hashed passwords. You would not have to ensure that two databases are always available at the same time, and always in sync. The advantage of having a salt is minimal if each user has a randomized salt because although it might make discovery of an individual’s password easier, the amount of force necessary to crack the passwords of the system overall will be high. In this level of discussion, that is really what the expectation is: to protect the passwords. If the hackers have acquired a copy of the database, your application data is already compromised. At this point, the issue is to mitigate users’ risks because of the potential of shared passwords. The requirement of maintaining two separate linked, databases is extensive. Granted, it adds the perception of security, but the only advantage that it gives is that it protects a password, a single element of data. If every field in the database were individually encrypted, and this same salt was used for that, it would make more sense to store it separately from the data because the basic security of your system is enhanced.

彩虹表的重点是,它们是预先创建的,并大量分布,以节省其他人的计算时间——实时生成彩虹表所需的时间与直接破解密码+salt组合所需的时间一样长(因为在生成彩虹表时,实际上所做的是预先运行计算以进行野蛮强制哈希),因此,通过知道盐就可以“生成彩虹表”的说法是虚假的。

在单独的文件中存储salt没有实际意义,只要它们是基于每个用户的——salt的意义只是为了使一个彩虹表不能破坏数据库中的每个密码。