簡體   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