我用光彦的实现PBKDF2的密码散列:PBKDF2和哈希比较
def pbkdf2_bin(data, salt, iterations=1000, keylen=24, hashfunc=None):
"""Returns a binary digest for the PBKDF2 hash algorithm of `data`
with the given `salt`. It iterates `iterations` time and produces a
key of `keylen` bytes. By default SHA-1 is used as hash function,
a different hashlib `hashfunc` can be provided.
"""
hashfunc = hashfunc or hashlib.sha1
mac = hmac.new(data, None, hashfunc)
def _pseudorandom(x, mac=mac):
h = mac.copy()
h.update(x)
return map(ord, h.digest())
buf = []
for block in xrange(1, -(-keylen // mac.digest_size) + 1):
rv = u = _pseudorandom(salt + _pack_int(block))
for i in xrange(iterations - 1):
u = _pseudorandom(''.join(map(chr, u)))
rv = starmap(xor, izip(rv, u))
buf.extend(rv)
return ''.join(map(chr, buf))[:keylen]
该函数返回二进制消化,然后在base64编码,并保存到数据库中。 。也是的base64字符串设定为当用户登录
此功能用于密码的cookie散列比较:
def comparePasswords(password1, password2):
if len(password1) != len(password2):
return False
diff = 0
for x, y in izip(password1, password2):
diff |= ord(x)^ord(y)
return diff == 0
我不知道是否有二进制散列和的base64字符串的比较有什么区别在安全方面?例如,当用户登录时,我计算提交的密码的二进制摘要,从数据库中解码base64字符串,然后比较两个二进制哈希值,但如果用户有base64字符串的cookie,我直接将其与来自数据库。
第二个问题是关于盐:
os.urandom返回二进制串,但它是在哈希生成使用之前我也编码它以base64。为什么我不应该这样做,并以二元形式使用盐,是否有任何理由?
对任何一个阅读:这是一个老问题,** PBKDF2不再是推荐的密码哈希算法**(尽管它比许多人们在实践中使用的破碎方案好得多)。如今这个称号属于** Argon2i **,是密码散列竞赛的赢家。 – 2017-10-20 07:39:23