2006-08-31

_ [ruby] openssl

しつこく続く

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

[]