使用Ruby解密在命令行上生成的盐化AES文件

Nic*_*las 3 ruby encryption openssl cryptography

我想在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
Run Code Online (Sandbox Code Playgroud)

在尝试找到答案时,我发现了AESCrypt gem宝石,据说该宝石简化了加密和解密,但是当前发布的版本与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
Run Code Online (Sandbox Code Playgroud)

但这导致OpenSSL::Cipher::CipherError: bad decrypt

我是否需要以某种方式专门处理文件已加盐?我已经阅读了OpenSSL文档中有关该enc函数的信息函数 IV(如果在加密文件时未指定)是从密码生成的。我是否需要以某种方式手动重建IV?

任何建议将不胜感激:)

cob*_*bal 5

OpenSSL使用自定义标头和密钥派生例程。Security.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
Run Code Online (Sandbox Code Playgroud)