上周我将 Fedora 升级到全新的 28 版本,它附带了 mongodb 升级到 3.6。请参阅升级到 Fedora 28 后如何修复 mongodb 服务?我如何设法解决我的第一个问题,即 mongod 将不再启动。现在我在使用同一个数据库的 Rails 应用程序上面临另一个问题。
这很可能与 mongodb 升级无关,但我认为提供该上下文可能值得,并且不要因为没有提供足够的上下文而错过解决方案。
因此,由于系统升级,此 Rails 项目上的任何登录尝试都会失败并出现错误,在初始化BCrypt::Errors::InvalidHash in Devise::SessionsController#create
时引发' `。bcrypt (3.1.11) lib/bcrypt/password.rb:60:in
在项目的 Rails 控制台中进一步分析,似乎对该方法的任何调用都会失败:
> BCrypt::Password.create('TestPassword')
BCrypt::Errors::InvalidHash: invalid hash
from /home/psychoslave/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/bcrypt-3.1.11/lib/bcrypt/password.rb:60:in `initialize'
我尝试bundle
卸载/重新安装bcrypt
,甚至使用 bcrypt gem 的 github 存储库版本,但它没有改变任何东西。
查看/home/psychoslave/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/bcrypt-3.1.11/lib/bcrypt/password.rb:60:in
初始化'`,问题似乎是哈希无效。
# Initializes a BCrypt::Password instance with the data from a stored hash.
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
对应的测试如下:
def valid_hash?(h)
h =~ /^\$[0-9a-z]{2}\$[0-9]{2}\$[A-Za-z0-9\.\/]{53}$/
end
哈希本身是通过创建的BCrypt::Engine.hash_secret(secret, BCrypt::Engine.generate_salt(cost))
,在我使用的平台中调用 call __bc_crypt(secret.to_s, salt)
,它似乎在调用bcrypt-3.1.11/ext/mri/bcrypt_ext.c。
更重要的是binding.pry
,在valid_hash?
方法中添加 a ,可以看到调用返回的哈希值是什么BCrypt::Password.create('TestPassword')
,它实际上是一个相当长的字符串,它的开头似乎很常见,但最终得到的最有可能是错误生成的序列:
"$2a$10$Eb1f8DSkGh4G1u5GicyTYujBk6SwFXKYCH.nqxapmBlqJ0eFYdX32\x00\x00\x00\x00\xD1F\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00T\xBD\x02\x00\x00\x00\x00\x00\xF1V\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\xE2\xB0\x02\x00\x00\x00\x
00\x00AW\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00 \x04\x00\x00\x00\x00\x00\x00\x86\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xB5\xF8\x0E\x00\x00\x00\x00\x00q\xD8\x01\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00…"
如果可能有任何兴趣,我可以提供整个哈希的转储(大约 32Ko!)。