さて、本題でもある 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