Расшифровка файла соленого AES, созданного в командной строке с помощью Ruby

#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