我正在编写一个需要使用现有Java Play框架应用程序的Django应用程序。 Play应用使用PasswordHash.java来存储密码。它以冒号分隔格式存储密码。每个哈希都存储为iterations
:salt
:pbkdf2_hash
。
例如,这是密码“test”的条目:
1000:f7fe4d511bcd33321747a778dd21097f4c0ff98f1e0eba39:b69139f51bc4098afc36b4ff804291b0bc697f87be9c1ced
在这里,我们可以将字符串拆分为:
并找到:
迭代:1000
盐:f7fe4d511bcd33321747a778dd21097f4c0ff98f1e0eba39
PBKDF2哈希:b69139f51bc4098afc36b4ff804291b0bc697f87be9c1ced
。
我修改了Django的check_password机制以兼容此格式,但发现它认为密码不正确。我使用Django的crypto.py来使用Play使用的相同的盐重新生成“test”的哈希值,并提出了这个:
hash = crypto.pbkdf2('test', 'f7fe4d511bcd33321747a778dd21097f4c0ff98f1e0eba39', 1000, 24)
base64.b16encode(hash)
'9A8725BA1025803028ED5B92748DD61DFC2625CC39E45B91'
播放中的PBKDF2哈希与此哈希不匹配。 (对于那些想知道的人,我使用24作为第四个参数,因为这是在PasswordHash.java中使用的。)
在我无法使Django生成的哈希匹配Java之后,我在website that does it for you.上尝试了
我插入相同的盐,使用SHA-1进行1000次迭代和24位密钥大小,发现网站与Django创建的匹配!
我不确定PasswordHash.java会发生什么,但我迫切需要让Django和Play“玩得很开心”(不能自己哈哈)。有没有人知道这里发生了什么?
答案 0 :(得分:3)
尝试salt = base64.b16decode(salt.upper())
。
我做了,我在你的初始例子中得到了哈希值,尽管是大写B69139F5...
说明:
哈希和salt都存储在初始示例中的Base16(hex)中。因此,您解码salt以使用它,然后对生成的哈希进行编码,以将其与存储的哈希值进行比较。
upper()
是因为python的b16decode
对大写Base16严格。如果你给它小写的话就会出错。