さて、本題でもある bf.rb や blowfishpr.rb が openssl ではうまくいかない原因を探るべく。
原因はなんとなく分かっていて、以下のような修正で行けるはず。
--- blowfishpr.rb.orig +++ blowfishpr.rb @@ -7,6 +7,7 @@ # Copyright (c) 2003-2005 Kazuhiro YOSHIDA # # You can redistribute it and/or modify it under the same terms as Ruby. +require "digest/md5" class BlowfishKey attr_accessor :PBox,:SBox @@ -66,6 +67,7 @@ def initialize(key) return if key == nil + key = Digest::MD5.digest(key) @PBox = [ 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, @@ -390,10 +392,10 @@ end def _crypt(s) o = '' - l, r = [] + l, r = 0, 0 (s.length / 8).times { - l = to32(s[0..3]) - r = to32(s[4..7]) + l ^= to32(s[0..3]) + r ^= to32(s[4..7]) s[0..7] = "" l,r = yield(l, r) (0..3).each{|n| o << from32(l, n)}
$ ruby -r blowfishpr.rb -e' print Blowfish.new("hoge").encrypt("nov_at_yo.rim.or.jp")' | \ openssl bf-cbc -d -nosalt -pass pass:hoge -iv 0000000000000000 -nopad | hd 00000000 6e 6f 76 5f 61 74 5f 79 6f 2e 72 69 6d 2e 6f 72 |nov_at_yo.rim.or| 00000010 2e 6a 70 00 00 00 00 00 |.jp.....| 00000018
ビンゴ!……なんだけど、encrypt だけで、decrypt ができなくなるワナ。 ダメじゃん!
$ ruby -r blowfishpr.rb -e' print Blowfish.new("hoge").encrypt("nov_at_yo.rim.or.jp")' | \ ruby -r blowfishpr.rb -e' print Blowfish.new("hoge").decrypt(ARGF.read)' | hd 00000000 6e 6f 76 5f 61 74 5f 79 b4 65 ab 0c 65 89 eb 4b |nov_at_y.e..e..K| 00000010 fe 47 2e d4 0d 02 1b 87 |.G......| 00000018
あと、pass から key と iv を得る方法だけど、
$ openssl bf-cbc -nosalt -pass pass: -P key=D41D8CD98F00B204E9800998ECF8427E iv =59ADB24EF3CDBE02
$ ruby -ropenssl -e' pass = ARGV.shift || "" md5 = OpenSSL::Digest::MD5.new key = md5.update(pass).digest iv = md5.update(key + pass).digest puts "key=%s" % key.unpack("H32").first.upcase puts "iv =%s" % iv.unpack("H16").first.upcase ' key=D41D8CD98F00B204E9800998ECF8427E iv =59ADB24EF3CDBE02
で行けそうに見えて、空文字列じゃないと
$ openssl bf-cbc -nosalt -pass pass:hoge -P key=EA703E7AA1EFDA0064EAA507D9E8AB7E iv =63413AFCBF321FFB
key=EA703E7AA1EFDA0064EAA507D9E8AB7E iv =3B4382B41384779E
と iv が合わないなぁ。EVP_BytesToKey(3SSL)はちょっと読みきれない。 もうちょっと C のソースを読む力が必要です。
というか、もう pure ruby じゃないんじゃないか?という感じがしてきたにょろ〜orz