2017-02-14 115 views
3

使用OpenSSL CLI,我可以使用几乎任何可以找到的ASCII字符串来加密值,只要它符合加密方法所需的长度。Ruby从预先存在的密钥字符串中创建密码密钥

例如:

printf 'flipflop' | openssl enc -K 2317823178123897237891232345345234524523452345 -iv 123789123789123789 -base64 -aes-256-cbc 

Pd4+UEBW1RyTjARy1rpndQ== 

printf 'Pd4+UEBW1RyTjARy1rpndQ==\n' | openssl enc -d -K 2317823178123897237891232345345234524523452345 -iv 123789123789123789 -base64 -aes-256-cbc 

flipflop 

但是如果我采取的关键,我们通过这个用Ruby运行:

require 'openssl' 

cipher = OpenSSL::Cipher::Cipher.new 'AES-256-CBC' 
cipher.encrypt 
cipher.key = "2317823178123897237891232345345234524523452345" 
cipher.iv = "123789123789123789" 
encrypted = cipher.update "flipflop" + cipher.final 
puts encrypted 

cipher = OpenSSL::Cipher::Cipher.new 'AES-256-CBC' 
cipher.decrypt 
cipher.key = "2317823178123897237891232345345234524523452345" 
cipher.iv = "123789123789123789" 
plain = cipher.update(encrypted) + cipher.final 
puts plain 

���ISq��Ҷ0�e� 
crypt.rb:14:in `final': bad decrypt (OpenSSL::Cipher::CipherError) 
    from crypt.rb:14:in `<main>' 

而且当我拿的base64从OpenSSL的命令,我得到了同样的坏解密:

require 'openssl' 
require 'base64' 

clear = Base64.decode64("Pd4+UEBW1RyTjARy1rpndQ==") 

cipher = OpenSSL::Cipher::Cipher.new 'AES-256-CBC' 
cipher.decrypt 
cipher.key = "2317823178123897237891232345345234524523452345" 
cipher.iv = "123789123789123789" 
plain = cipher.update(clear) + cipher.final 
puts plain 

crypt.rb:10:in `final': bad decrypt (OpenSSL::Cipher::CipherError) 
    from crypt.rb:10:in `<main>' 

我相信这里发生的是,OpenSSL正在转换我的cip她的钥匙和IV是一种方式,而红宝石则是另一种方式。例如,当您使用PBKDF2创建密钥时,您会得到一串十六进制值,即:“\ x00 \ AF ...”。

这是问题吗?我需要将我的字符串转换为特定格式?我怎么做?这不是问题吗?

+0

还要注意的是,在的OpenSSL 1.1.0改变默认的命令行值。它为那些在1.0.2(或更低版本)中使用'openssl enc',然后在1.1.0及更高版本中使用'openssl dec'的人们带来了相当大的麻烦。另请参阅OpenSSL用户列表上的[解密旧的openssl文件](https://mta.openssl.org/pipermail/openssl-users/2017-February/005270.html)。 – jww

回答

3

这里有几个问题。

你的Ruby往返代码是不工作,因为这行:

encrypted = cipher.update "flipflop" + cipher.final 

它应该是:

encrypted = cipher.update("flipflop") + cipher.final 

这是给造成bad decrypt错误错误的加密。否则,该代码应该可以工作,尽管它使用的命令行版本与键和ivs不同。但是,它仅适用于旧版本的Ruby和OpenSSL绑定。当前版本的Ruby的OpenSSL库检查提供的keyiv的长度,并在出错时引发异常。对于aes-256-cbc,它们应该分别是32和16字节。

openssl enc命令的-K-iv选项接受十六进制编码的字符串,然后将其解码为原始字节。它还用零字节填充这些值直到它们长度合适。

这里是你如何解密命令行加密字符串在Ruby中:

# Base64 cipher text from the question: 
message = "Pd4+UEBW1RyTjARy1rpndQ==" 
message = Base64.decode64(message) 

key = "2317823178123897237891232345345234524523452345" 
#Convert from hex to raw bytes: 
key = [key].pack('H*') 
#Pad with zero bytes to correct length: 
key << ("\x00" * (32 - key.length)) 

iv ="123789123789123789" 
#Convert from hex to raw bytes: 
iv = [iv].pack('H*') 
#Pad with zero bytes to correct length: 
iv << ("\x00" * (16 - iv.length)) 

cipher = OpenSSL::Cipher.new('AES-256-CBC') 
cipher.decrypt 
cipher.key = key 
cipher.iv = iv 
plain = cipher.update(message) + cipher.final 
puts plain # => 'flipflop' 
+0

美丽,我会在第二秒试试。感谢信息马特。 – Breedly