我认为如何在数据库中存储密码的建议存在矛盾。 我们对密码进行哈希并将其存储在DB中,当用户尝试登录时,我们以相同的方式对其输入字符串进行哈希并与数据库进行比较。没关系。 但是有建议通过添加随机盐来强化该哈希值。 这是问题所在: 所以我们失去了整个比较点,因为在存储在DB中的第一个哈希值和登录时的盐之间的盐值会有所不同吗? 如果将盐储存在Db中,那么腌制的好处是什么?
答案 0 :(得分:6)
您还存储盐。比较是在存储的哈希值和{{1}}之间。 salt的目的是防止使用相同密码的两个用户生成相同的哈希值。
答案 1 :(得分:0)
我们为每个密码生成随机盐的原因是,无法构建单个rainbowtable来一次获取所有密码。相反,攻击者必须为每个salt /密码构建一个rainbowtable。构建rainbowtable以获取单个密码毫无意义,因为如果找到匹配项,您可以停止搜索。
换句话说,腌制可以防止使用彩虹纸。即使盐是已知的,仍然需要为每个密码构建一个rainbowtable,这样就可以实现这个目的,这就是为什么我们可以将盐与哈希一起存储在数据库中。
顺便说一下:SHA- *哈希函数不适合哈希密码,而应该使用密码哈希函数,如BCrypt,SCrypt,PBKDF2或Argon2。它们都有成本因素使散列变慢。
修改强>
以下示例仅为了更好地理解,不应以这种方式添加盐:
1. Example with the same (global) salt for all passwords:
hash("Password1"+"o9*eiwrC49YAS2395%tu") => hash1
hash("Password2"+"o9*eiwrC49YAS2395%tu") => hash2
hash("Password3"+"o9*eiwrC49YAS2395%tu") => hash3
要找出Password1,我们可以构建一个包含所有合理密码和全局盐的查找表。为了找到Password2,我们可以重用相同的查找表,因为所有密码都使用相同的全局盐。
2. Example with unique salts for each password:
hash("Password4"+"ierukElasidj42Swiekq") => hash4
hash("Password5"+"oeuoElwWPJckfk212344") => hash5
hash("Password6"+"PoiMnmdvhas98akd73lk") => hash6
要查找Password4,我们必须使用所有合理的密码和salt "ierukElasidj42Swiekq"
构建1个查找表。要找出Password5,必须使用salt "oeuoElwWPJckfk212344"
构建另一个查找表,依此类推。第一个示例需要1个查找表,第二个示例需要与密码一样多的查找表。