我正在重写
Ruby on Rails中的Django应用程序,并希望保留用户的旧密码.
Django使用PBKDF2SHA1作为加密机制.所以我有一个加密密码就是这个
pbkdf2_sha256$10000$YsnGfP4rZ1IZ$Tpf4922MoNEjuJQA9EG2Elptyt3dMAyzBPUgmunFOW4=
原始密码是2bulls
在Ruby中,我使用PBKDF256 gem和base64进行检查.
Base64.encode64 PBKDF256.dk("2bulls","YsnGfP4rZ1IZ",10000,32)
我期待着
Tpf4922MoNEjuJQA9EG2Elptyt3dMAyzBPUgmunFOW4=
但是,我得到了
YEfK6oUGFHdaKZMDXC0Dz8TpwsJlKfqC5vjCxjo+ldU=
有任何想法吗?
UPDATE
class PBKDF2PasswordHasher(BasePasswordHasher): """ Secure password hashing using the PBKDF2 algorithm (recommended) Configured to use PBKDF2 + HMAC + SHA256 with 10000 iterations. The result is a 64 byte binary string. Iterations may be changed safely but you must rename the algorithm if you change SHA256. """ algorithm = "pbkdf2_sha256" iterations = 10000 digest = hashlib.sha256 def encode(self,password,salt,iterations=None): assert password assert salt and '$' not in salt if not iterations: iterations = self.iterations hash = pbkdf2(password,iterations,digest=self.digest) hash = base64.b64encode(hash).decode('ascii').strip() return "%s$%d$%s$%s" % (self.algorithm,hash) def verify(self,encoded): algorithm,hash = encoded.split('$',3) assert algorithm == self.algorithm encoded_2 = self.encode(password,int(iterations)) return constant_time_compare(encoded,encoded_2) def safe_summary(self,3) assert algorithm == self.algorithm return SortedDict([ (_('algorithm'),algorithm),(_('iterations'),iterations),(_('salt'),mask_hash(salt)),(_('hash'),mask_hash(hash)),])
结论:
事实证明只有2bulls作为密码的帐户才有这个问题.其他帐户都没问题.当我知道2bulls密码不一致的确切原因时,我会在这里发布.
解决方法
如果你使用以下脚本(与Django用来散列密码的逻辑相同)散列密码2bulls,这就是你得到的(在Django的shell上运行):
>>> import base64,hashlib >>> hash = pbkdf2("2bulls",32,hashlib.sha256) >>> hash.encode('base64').strip() 'YEfK6oUGFHdaKZMDXC0Dz8TpwsJlKfqC5vjCxjo+ldU='
请注意我是如何使用您在Ruby中使用的相同参数:
password = "2bulls" salt = "YsnGfP4rZ1IZ" iterations = 10000 dklen = 32 digest = hashlib.sha256
您确定您的预期哈希对应于密码2bulls吗?