На прошлой неделе я обновил 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!).