2011-11-09 31 views
7

Tại sao có sự khác biệt trong mã hóa blowfish giữa Crypt :: CBC (perl) và OpenSSL (ruby)?Sự khác biệt trong mã hóa blowfish giữa perl và ruby ​​

Perl

use Crypt::CBC; 

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

# ciphertext is 53616c7465645f5f409c8b8eb353823c06d9b50537c92e19 

của Ruby

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 

Crypt :: CBC dường như được thêm vào trước Salted__ để đầu ra theo mặc định. Bạn có thể giải thích những gì đang xảy ra mà là rất khác nhau giữa những? Có cách nào để làm cho OpenSSL hoạt động theo cách tương tự như Crypt :: CBC không?

+2

Kịch bản Perl tạo ra đầu ra khác nhau mỗi khi nó được chạy. 8 byte trong đầu ra sau "Salted__" là muối mà mô-đun được sử dụng để mã hóa văn bản (Tôi không biết liệu thông tin đó có hữu ích hay không). – mob

+0

@mob: Điều đó thực sự giải thích nó. Đó là vectơ khởi tạo. Nếu không, một đầu vào cho trước luôn mã hóa cùng một điều, tiết lộ thông tin. Joepestro, điều này có thể rơi vào "tại sao bạn phát minh ra giao thức mật mã của riêng bạn" – derobert

Trả lời

7

Crypt :: CBC (perl) sử dụng riêng hod để ngẫu nhiên muối và vector khởi tạo. Cộng với trường hợp Blowfish, nó sử dụng độ dài khóa 56 như đã đề cập ở trên.

Sử dụng mã perl từ ví dụ của bạn:

Perl

use Crypt::CBC; 

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

Để giải mã này sử dụng ruby ​​(OpenSSL) đòi hỏi một chút tinh chỉnh để trích xuất các chìa khóa và khởi tạo vector:

Ruby

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

Hóa ra mặc định kích thước khóa blowfish khác nhau giữa hai loại này. OpenSSL mặc định là 16, Crypt :: Blowfish mặc định là 56.

Bạn có thể ghi đè kích thước khóa trong Crypt :: CBC bằng cách chỉ định -keysize => n, nhưng tiếc là dường như không có cách nào để ghi đè kích thước khóa trong OpenSSL.

OpenSSL thư viện mặc định là 16 byte kích thước khóa Blowfish, vì vậy cho khả năng tương thích với OpenSSL bạn có thể muốn đặt -keysize => 16

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

Perl (ghi rõ keysize)

my $cipher = Crypt::CBC->new( 
    -key => 'length32length32length32length32', 
    -keysize => 16, 
    -cipher => 'Blowfish' 
); 
Các vấn đề liên quan