2017-02-14 111 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