请问有谁能帮我理解盐值是如何工作的吗?
目前我了解到以下内容:
- 验证密码
- 生成一个随机字符串
- 将密码和随机字符串进行哈希运算并连接起来,然后将它们存储在密码字段中...
我们如何存储盐值,或者在用户登录时知道它是什么呢?我们是否将其存储在单独的字段中?如果我们不这样做,应用程序如何找出盐值是什么?如果我们确实存储了它,那不是完全违背了盐值的作用吗?
请问有谁能帮我理解盐值是如何工作的吗?
目前我了解到以下内容:
我们如何存储盐值,或者在用户登录时知道它是什么呢?我们是否将其存储在单独的字段中?如果我们不这样做,应用程序如何找出盐值是什么?如果我们确实存储了它,那不是完全违背了盐值的作用吗?
在哈希之前,将盐与密码组合。将密码和盐值清晰的值连接在一起,然后对生成的字符串进行哈希。这保证了即使两个人拥有相同的密码,也会产生不同的哈希结果。(同时使得使用彩虹表等字典攻击更加困难)。
然后,将盐以原始/明文格式与哈希结果一起存储。稍后,当您想要验证密码时,需要再次执行原始过程。将记录中的盐与用户提供的密码组合,哈希结果,比较哈希。
您可能已经知道这一点了,但很重要的是记住。盐必须每次随机生成。它必须对于每个受保护的哈希都不同。通常使用 RNG 生成盐。
例如:
用户密码:"mypassword"
随机盐:"abcdefg12345"
生成的明文:"mypassword:abcdefg12345" (如何组合它们取决于您,只要每次使用相同的组合格式即可)。
对生成的明文进行哈希:"基于算法的某些标准长度哈希"
现在在您的数据库中,您将存储使用的哈希和盐。我见过两种方法:
方法1:
字段1-盐="abcdefg12345"
字段2-密码哈希="基于算法的某些标准长度哈希"
方法2:
字段1-密码哈希="abcdefg12345:基于算法的某些标准长度哈希"
在任一种情况下,您都必须从数据库中加载盐和密码哈希,并重新执行哈希以进行比较。
salt <- random
hash <- hash(password + salt)
store hash:salt
稍后
input password
look up hash:salt
hash(password+salt)
compare with stored hash
明白了吗?
x[0] := 0
x[i] := h(x[i-1] || p || s) for i = 1, ..., r
K := x[r]
where
h is the hash (SHA-1, SHA-256, etc.)
K is the generated hashed password
p is the plaintext password
r is the number of rounds
s is the randomly generated salt
|| is the concatenation operator
盐值是与加密密码一起存储的随机数,不需要保密。
拉伸是多次执行哈希以使攻击者难以测试多个密码组合的行为。应选择r
,使计算在用户计算机上大约需要200-1000毫秒。随着计算机速度的提高,可能需要增加r
。