使用 Ruby 解密在命令行上生成的盐渍 AES 文件 [英] Decrypting salted AES file generated on command line with Ruby
问题描述
我想解密之前使用 OpenSSL 的命令行工具加密的 ruby 2.1 脚本中的文本文件:openssl enc -aes-256-cbc -a -salt -in my_file
I would like to decrypt a text file within a ruby 2.1 script which was previously encrypted using OpenSSL's commandline tools:
openssl enc -aes-256-cbc -a -salt -in my_file
从命令中可以看出,该文件经过 AES-256-CBC 加密、加盐和 base64 编码.
As seen in the command, the file is AES-256-CBC encrypted, salted and base64 encoded.
密码是已知的,但不是 IV 或密钥,它们是遵循此代码片段所必需的,取自 ruby 文档:
The password is known, but not the IV nor the key, which are required to follow this code snippet, taken from the ruby documentation:
decipher = OpenSSL::Cipher::AES.new 256, :CBC
decipher.decrypt
decipher.key = key
decipher.iv = iv
plain = decipher.update(encrypted_text) + decipher.final
在尝试寻找答案时,我发现了 gem AESCrypt gem,据说可以简化加密和解密,但当前发布的版本与 ruby 2.1 不兼容.查看它的源代码,我发现密钥是 通过摘要检索得到的密码,而 IV 仅保留为 <代码>无.
While trying to find an answer, I found the gem AESCrypt gem which supposedly simplifies en- and decrypting, yet the currently released version is not compatible with ruby 2.1.
Looking at it's source code, I found that the key was retrieved by digesting the password, and the IV is just left as nil
.
所以我试图让以下运行:
So I tried to get the following running:
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.我是否需要以某种方式手动重建 IV?
Do I need to somehow specifically handle that the file is salted? I have read in the OpenSSL documentation for the enc
function that the IV, if not specified while encrypting the file, is generated from the password. Do I need to manually reconstruct the IV somehow?
任何建议将不胜感激:)
Any advice would be highly appreciated :)
推荐答案
OpenSSL 使用自定义标头和密钥派生例程.Security.SE 对标头有很好的描述 和 EVP_BytesToKey
的文档描述了密钥派生.
OpenSSL uses a custom header and key derivation routine. Security.SE has a good description of the header and the docs for EVP_BytesToKey
describe the key derivation.
我们可以修改您的代码以使用这种奇怪且有些损坏的密钥派生,如下所示:
We can modify your code to use this weird and somewhat broken key derivation as follows:
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
这篇关于使用 Ruby 解密在命令行上生成的盐渍 AES 文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!