Почему BCrypt больше не принимает хэши? - PullRequest
0 голосов
/ 07 мая 2018

На прошлой неделе я обновил Fedora до новой версии 28, которая вышла с обновлением mongodb до 3.6. См. Как восстановить службу mongodb после обновления до Fedora 28? , чтобы узнать, как мне удалось решить мою первую проблему, заключающуюся в том, что mongod больше не запускается. Теперь я столкнулся с другой проблемой в приложении Rails, которое использует эту же базу данных.

Скорее всего, это не связано с обновлением mongodb, но я подумал, что, возможно, стоит предоставить этот контекст и не упустить решение из-за его недостаточного количества.

Таким образом, поскольку при обновлении системы любая попытка входа в этот Rails-проект завершится неудачей с ошибкой BCrypt::Errors::InvalidHash in Devise::SessionsController#create , возникшей в bcrypt (3.1.11) lib/bcrypt/password.rb:60:in initialize'`. Анализируя далее в консоли проекта 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 и даже использовать вместо этого версию gcub для хранилища bcrypt, но это ничего не изменило.

Глядя на /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'`, проблема кажется в том, что хеш недействителен.

# 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.pry в метод valid_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!).

Ответы [ 2 ]

0 голосов
/ 30 января 2019

У меня была эта проблема с (очень) старым приложением и BCrypt 3.1.10. Обновление до 3.1.12 решило проблему. :)

0 голосов
/ 07 мая 2018

Вот обходное решение, которое заставляет rspec из bcrypt снова успешно пройти все тесты.

Это действительно ужасный хак, ожидающий правильного решения, но до тех пор выполняет свою работу. Просто измените ~/.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", если есть.

Примечание: эта версия взлома была предложена Андрей Ситник , и я заменил тот, который я предложил здесь самостоятельно, прежде чем обнаруживать его.

После этого BCrypt :: Password # create снова заработает:

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