2011-11-09 56 views
7

爲什麼Crypt :: CBC(perl)和OpenSSL(ruby)之間的blowfish加密有什麼區別?perl和ruby之間的blowfish加密的區別

的Perl

use Crypt::CBC; 

my $cipher = Crypt::CBC->new(-key => 'length32length32length32length32', -cipher => 'Blowfish'); 
my $ciphertext = $cipher->encrypt_hex('test'); 

# ciphertext is 53616c7465645f5f409c8b8eb353823c06d9b50537c92e19 

紅寶石

require "rubygems" 
require "openssl" 

cipher = OpenSSL::Cipher::Cipher.new("bf-cbc") 
cipher.encrypt 
cipher.key = "length32length32length32length32" 

result = cipher.update("test") << cipher.final 
ciphertext = result.unpack("H*").first 

# ciphertext is 16f99115a09e0464 

地穴:: CBC似乎要在前面加上Salted__到系統默認的輸出。你能解釋一下這是怎麼回事嗎?有沒有辦法讓OpenSSL的行爲與Crypt :: CBC類似?

+2

Perl腳本每次運行時都會生成不同的輸出。 「Salted__」之後輸出中的8個字節是模塊用於加密文本的鹽(我不知道該信息是否有用)。 – mob

+0

@mob:這實際上解釋了它。這是初始化向量。否則,給定的輸入總是加密爲相同的東西,從而公開信息。 Joepestro,這可能屬於「你爲什麼要發明自己的密碼協議」 – derobert

回答

7

Crypt :: CBC(perl)使用自己的met以隨機化鹽和初始化向量。另外在Blowfish的情況下,它使用上面提到的56的密鑰長度。

使用從您的示例Perl代碼:

的Perl

use Crypt::CBC; 

my $cipher = Crypt::CBC->new(-key => 'length32length32length32length32', -cipher => 'Blowfish'); 
my $ciphertext = $cipher->encrypt_hex('test'); 
# 53616c7465645f5f409c8b8eb353823c06d9b50537c92e19 

解碼此使用紅寶石(OpenSSL的)需要一些調整來提取密鑰和初始化向量:

紅寶石

require 'openssl' 

# Hex string to decode(from above) 
string = '53616c7465645f5f409c8b8eb353823c06d9b50537c92e19' 

# Pack Hex 
string = [string].pack('H*') 

# Some Config 
pass = 'length32length32length32length32' 
key_len = 56; 
iv_len = 8; 
desired_len = key_len + iv_len; 
salt_re = /^Salted__(.{8})/ 

#Extract salt 
salt = salt_re.match(string) 
salt = salt.captures[0] 
data = ''; 
d = ''; 
while (data.length < desired_len) 
    d = Digest::MD5::digest("#{d}#{pass}#{salt}"); 
    data << d; 
end 

#Now you have extracted your key and initialization vector 
key = data.slice(0..key_len-1) 
iv = data.slice(key_len .. -1) 

# Trim string of salt 
string = string[16..-1] 

cipher = OpenSSL::Cipher::Cipher.new "bf-cbc" 
cipher.decrypt 
cipher.key_len = key_len 
cipher.key = key 
cipher.iv = iv 

puts cipher.update(string) << cipher.final 
# test 
1

原來這兩個河豚密鑰大小的默認值是不同的。 OpenSSL默認爲16,Crypt :: Blowfish默認爲56.

您可以通過指定-keysize => n來覆蓋Crypt :: CBC中的密鑰大小,但不幸的是似乎沒有辦法覆蓋OpenSSL中的密鑰大小。

OpenSSL庫默認爲16字節的Blowfish密鑰大小,所以對於使用OpenSSL 兼容性您可能希望-keysize設定=> 16

http://metacpan.org/pod/Crypt::CBC

的Perl(指定密鑰長度)

my $cipher = Crypt::CBC->new( 
    -key => 'length32length32length32length32', 
    -keysize => 16, 
    -cipher => 'Blowfish' 
);