繁体   English   中英

为什么BCrypt不再接受哈希?

[英]Why does BCrypt no longer accept hashes?

上周我将Fedora升级到全新的28版本,其中mongodb升级到3.6。 请参阅升级到Fedora 28后如何修复mongodb服务? 因为我设法解决了我的第一个问题,即mongod将不再启动。 现在我在使用同一个数据库的Rails应用程序上面临另一个问题。

这很可能与mongodb升级无关,但我认为值得提供上下文并且不要错过没有提供足够的上下文的解决方案。

因此,自系统升级以来,对这个Rails项目的任何登录尝试都将失败, BCrypt::Errors::InvalidHash in Devise::SessionsController#create了一个BCrypt::Errors::InvalidHash in Devise::SessionsController#create错误,在bcrypt (3.1.11) lib/bcrypt/password.rb:60:in提出了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 initialize'`,the问题似乎哈希无效。

# 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)) ,在我使用的平台中调用__bc_crypt(secret.to_s, salt) ,这似乎是在调用bcrypt-3.1 .11 / ext / mri / bcrypt_ext.c

更重要的是,加入binding.pryvalid_hash? 方法,可以看到为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!),我可以提供整个哈希的转储。

这是一个规避解决方案,使得bcrypt rspec再次成功通过所有测试。

在等待合适的解决方案时,这真的是一个糟糕的黑客,但直到那时才完成工作。 只需更改~/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/bcrypt-3.1.11/lib/bcrypt/engine.rb (当然要适应的路径),第51行来自:

- __bc_crypt(secret.to_s, salt)
+ __bc_crypt(secret.to_s, salt).gsub(/(\n|\x00).*/, '')

也就是说,如果有的话,从第一个“\\ x00”或“\\ n”出现开始中继字符串。

信用说明: 此版本的黑客攻击是Andrey Sitnik提出的,在发现它之前,我取代了我在这里独立提出的版本。

之后,BCrypt :: Password#create将再次运行:

> BCrypt::Password.create('TestPassword')
=> "$2a$10$YPRnQF3ZihXHpa9kSx7Mpu.j28PlbdwaNs2umSQvAGkS.JJ.syGye"

我有一个(非常)旧的应用程序和BCrypt 3.1.10这个问题。 升级到3.1.12解决了这个问题。 :)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM