最近,当我尝试使用密码保存记录时,我开始收到BCrypt“无效哈希”错误,因此我查看了BCrypt代码,发现了以下用于验证密码的方法:
def valid_hash?(h)
h =~ /^\$[0-9a-z]{2}\$[0-9]{2}\$[A-Za-z0-9\.\/]{53}$/
end
[initialize
方法调用:
def initialize(raw_hash)
if valid_hash?(raw_hash)
self.replace(raw_hash)
@version, @cost, @salt, @checksum = split_hash(self)
else
raise Errors::InvalidHash.new("invalid hash")
end
end
以下密码:
"PassiveForbearenceFox"
"VindictivePurpleAlligator12345"
"LostBlueLizard!@#$1234"
全部返回无效哈希值错误。
更新:
我深入研究,发现正则表达式正在检查散列密码,但是由于某种原因而被传递的散列后面有无穷的/x00
流。例如,如果我输入密码“ LostBlueLizard!@#1234”,则传递给挑战正则表达式的哈希是
"$2a$11$NcmldbbyCDfumGYALgYhfuIQt2FZ8gpbVCQfuiVlwjhCtkD2ndDFy\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\.....
等等,比我能滚动的还要远。
如果我删除\x00
并仅传递$2a$11$NcmldbbyCDfumGYALgYhfuIQt2FZ8gpbVCQfuiVlwjhCtkD2ndDFy
,它将通过正则表达式。
没有人知道为什么哈希中包含这些字符吗?我无法证明以前没有密码,但是直到最近我的密码始终都被接受。
更新2:
此外,实际上是raw_hash
被输入到initialize
方法中,该方法是所有\x00
的散列。因此,某处有代码生成错误的哈希并将其传递给initialize
,但是我在整个gem的代码库中搜索了“初始化”一词,但没有类似的结果,因此我无法找到哈希实际生成的位置。
更新3:
[好的,我进一步追踪了这个问题,到了BCrypt::Engine.create
方法,该方法调用了__bc_crypt
方法,这将返回错误的哈希值。但是__bc_crypt
实际上来自名为“ ext / mri / bcrypt_ext.c”的文件,并且使用C语言编写,我认为这超出了我的研究范围。
我只是简单地将BCrypt从3.1.11更新为3.1.13,现在可以正常工作了。我不确定这是否是错误,但关键是现在可以使用。
这并不意味着Bcrypt的valid_hash吗?方法错误,表示存储的密码无效或与有效哈希系统不匹配的nil。
您可能必须添加
has_secure_password
如果没有,请在此之后检查password_digest字段。