ruby - perl 和 ruby​​ 之间河豚加密的区别

标签 ruby perl encryption openssl blowfish

为什么 Crypt::CBC (perl) 和 OpenSSL (ruby) 之间的河豚加密存在差异?

Perl

use Crypt::CBC;

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

# ciphertext is 53616c7465645f5f409c8b8eb353823c06d9b50537c92e19

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 似乎默认在输出前加上 Salted__。你能解释一下它们之间如此不同的原因吗?有没有办法让 OpenSSL 的行为类似于 Crypt::CBC?

最佳答案

Crypt::CBC (perl) 使用它自己的方法来随机化 salt 和初始化向量。另外,在 Blowfish 的情况下,它使用的 key 长度为 56,如上所述。

使用示例中的 perl 代码:

Perl

use Crypt::CBC;

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

要使用 ruby​​ (OpenSSL) 对此进行解码,需要进行一些调整以提取 key 和初始化向量:

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   

关于ruby - perl 和 ruby​​ 之间河豚加密的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8073365/

相关文章:

multithreading - perl 模块 Perl-LDAP (Net::LDAP) 是线程安全的吗?

c++ - 使用堆栈加密字符串

php - 在 PHP 文件中存储加密 key 的安全性

ruby-on-rails - 嵌套路由重定向以使用错误的路由创建操作

ruby-on-rails - ElasticSearch + Rails多个 `must`无法正常工作

ruby - 如何同时捕获不同的错误类型?

perl - 如何从 perl 中的 IO::Async::Loop 事件中删除 IO::Async::Listener (或其通知程序)对象

linux - 如何杀死 fork 进程?

ruby-on-rails - Sqlite3 gem 未加载,在项目中安装并指定了 gem

encryption - clojure 有 AES 库吗?