使用Ruby在命令行上解密加密的AES文件 [英] Decrypting salted AES file generated on command line with Ruby

查看:99
本文介绍了使用Ruby在命令行上解密加密的AES文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想解密一个ruby 2.1脚本中的文本文件,该脚本以前使用OpenSSL的命令行工具加密:
openssl enc -aes-256-cbc -a -salt -in my_file



如命令所示,该文件是AES-256-CBC加密,盐化和base64编码。



密码是已知的,但不是IV或密钥,需要遵循此代码段,取自 ruby​​ documentation

  decipher = OpenSSL :: Cipher :: AES.new 256,:CBC 
decipher.decrypt
decipher.key = key
decipher.iv = iv

plain = decipher.update(encrypted_text)+ decipher.final

在尝试找到答案时,我发现了宝石 AESCrypt 宝石suppos edly简化了ena和解密,但目前发布的版本与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

解密= 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

但是, code> OpenSSL :: Cipher :: CipherError:bad decrypt 。



我需要以某种方式专门处理该文件被盐渍?我已阅读 OpenSSL文档中的 enc 函数如果在加密文件时没有指定IV,则从密码生成。我需要手动重建IV吗?



任何建议将被高度赞赏:)

解决方案

OpenSSL使用自定义标题和密钥导出例程。 Security.SE有一个很好的描述标题 docs for 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]

解密= 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


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

As seen in the command, the file is AES-256-CBC encrypted, salted and base64 encoded.

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

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

But this results in OpenSSL::Cipher::CipherError: bad decrypt.

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 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆