我正在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=
有什么想法吗?
更新
如果对你更有意义,可以在django源代码中找到代码。
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, salt, iterations, digest=self.digest)
hash = base64.b64encode(hash).decode('ascii').strip()
return "%s$%d$%s$%s" % (self.algorithm, iterations, salt, hash)
def verify(self, password, encoded):
algorithm, iterations, salt, hash = encoded.split('$', 3)
assert algorithm == self.algorithm
encoded_2 = self.encode(password, salt, int(iterations))
return constant_time_compare(encoded, encoded_2)
def safe_summary(self, encoded):
algorithm, iterations, salt, hash = encoded.split('$', 3)
assert algorithm == self.algorithm
return SortedDict([
(_('algorithm'), algorithm),
(_('iterations'), iterations),
(_('salt'), mask_hash(salt)),
(_('hash'), mask_hash(hash)),
])
结论:
事实证明,只有使用2bulls作为密码的帐户才会出现此问题。其他帐户都没问题。当我知道2bulls密码不一致的确切原因时,我会在这里发帖。
答案 0 :(得分:6)
如果使用以下脚本(与Django用于散列密码的逻辑相同)散列该密码2bulls
,这就是你得到的(在Django&shell;上运行它):
>>> import base64, hashlib
>>> hash = pbkdf2("2bulls","YsnGfP4rZ1IZ", 10000, 32, hashlib.sha256)
>>> hash.encode('base64').strip()
'YEfK6oUGFHdaKZMDXC0Dz8TpwsJlKfqC5vjCxjo+ldU='
请注意我如何使用您在Ruby中使用的相同参数:
password = "2bulls"
salt = "YsnGfP4rZ1IZ"
iterations = 10000
dklen = 32
digest = hashlib.sha256
您确定您的预期哈希值对应于密码2bulls
吗?
答案 1 :(得分:0)
我刚刚为此目的发布了一颗宝石。我也是,得到与@Daniel Aronne相同的结果:
require 'pbkdf2_password_hasher'
puts Pbkdf2PasswordHasher::hash_password('2bulls','YsnGfP4rZ1IZ',10000,32)
#=> "YEfK6oUGFHdaKZMDXC0Dz8TpwsJlKfqC5vjCxjo+ldU="