#ruby #encryption #openssl
#ruby #шифрование #криптография #openssl
Вопрос:
Я хотел бы расшифровать текстовый файл в скрипте ruby 2.1, который ранее был зашифрован с помощью инструментов командной строки OpenSSL: openssl enc -aes-256-cbc -a -salt -in my_file
Как видно из команды, файл зашифрован AES-256-CBC, зашифрован соленым и закодирован на base64.
Пароль известен, но не IV и не ключ, которые требуются для выполнения этого фрагмента кода, взятого из документации ruby:
decipher = OpenSSL::Cipher::AES.new 256, :CBC
decipher.decrypt
decipher.key = key
decipher.iv = iv
plain = decipher.update(encrypted_text) decipher.final
Пытаясь найти ответ, я нашел драгоценный камень AESCrypt, который предположительно упрощает en- и расшифровку, но выпущенная в настоящее время версия несовместима с ruby 2.1.
Просматривая его исходный код, я обнаружил, что ключ был получен путем переваривания пароля, а IV просто оставлен как nil
.
Итак, я попытался запустить следующее:
encoded_and_encrypted_text = File.read my_file_path
encrypted_text = Base64.decode64 encoded_and_encrypted_text.to_s.strip
decipher = OpenSSL::Cipher::AES.new 256, :CBC
decipher.decrypt
decipher.key = OpenSSL::Digest::SHA256.new(my_password).digest
plain_text = decipher.update(encrypted_text) decipher.final
Но это приводит к OpenSSL::Cipher::CipherError: bad decrypt
.
Нужно ли мне как-то конкретно обрабатывать, что файл соленый? Я прочитал в документации OpenSSL для enc
функции, что IV, если он не указан при шифровании файла, генерируется из пароля. Нужно ли мне каким-то образом вручную восстанавливать IV?
Любые советы будут высоко оценены 🙂
Комментарии:
1. Попробуйте и найдите код, который реализует
EVP_BytesToKey
… Хорошо, теперь один из них приведен ниже, я думаю, вам не нужно далеко ходить.
Ответ №1:
OpenSSL использует пользовательский заголовок и процедуру получения ключа. Безопасность.SE имеет хорошее описание заголовка и документы для EVP_BytesToKey
описания получения ключа.
Мы можем изменить ваш код, чтобы использовать этот странный и несколько неработающий вывод ключа следующим образом:
encoded_and_encrypted_text = File.read my_file_path
encrypted_text = Base64.decode64 encoded_and_encrypted_text.to_s.strip
header = encrypted_text[0,8]
salt = encrypted_text[8,8]
payload = encrypted_text[16..-1]
decipher = OpenSSL::Cipher::AES.new 256, :CBC
decipher.decrypt
D_1 = OpenSSL::Digest::MD5.new(my_password salt).digest
D_2 = OpenSSL::Digest::MD5.new(D_1 my_password salt).digest
D_3 = OpenSSL::Digest::MD5.new(D_2 my_password salt).digest
decipher.key = (D_1 D_2)
decipher.iv = D_3
plain_text = decipher.update(payload) decipher.final
Комментарии:
1. Мне кажется, что
EVP_BytesToKey
все в порядке. Заголовок Salt также присутствует. 🙂2. @owlstead Да, это именно развернутая версия описания в openssl.org/docs/crypto/EVP_BytesToKey.html