それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

Hello Worldを 2進数の0/1 にバイナリに変換してランダムパッド(使い捨て暗号

バイナリ変換してXORして遊びたい

暗号技術入門を呼んでいると、XORがバンバン出てくるので、ちょっとやってみようと思い立った

暗号技術入門 第3版

暗号技術入門 第3版

ruby で計算するのが早い

>> "Hello".each_byte.map{|e| e }.join(" | " )
=> "72 | 101 | 108 | 108 | 111"
>> "Hello".each_byte.map{|e|  sprintf("%b", e)  }.join(" | " )
=> "1001000 | 1100101 | 1101100 | 1101100 | 1101111"

これをXORと併せて計算しましょう

本当は、C言語のプログラミングの授業でやりたいんだけどねぇ。

Ruby で ランダムパッドをして遊ぶ。

>> "Hello".each_char.zip( "World".each_char )
=> [["H", "W"], ["e", "o"], ["l", "r"], ["l", "l"], ["o", "d"]]
>> "Hello".each_byte.zip( "World".each_byte ).map{|e| e[0] ^ e[1] }
=> [31, 10, 30, 0, 11]
>> "Hello".each_byte.zip( "World".each_byte ).map{|e| e[0] ^ e[1] }
=> [31, 10, 30, 0, 11]
>> "Hello".each_byte.zip( "World".each_byte ).map{|e| e[0] ^ e[1] }.zip("World".each_byte).map{|e| e[0] ^ e[1] }.map(&:chr).join
=> "Hello"
>>

Hello を World で XORで符号化する

>> "Hello".each_byte.zip( "World".each_byte ).map{|e| e[0] ^ e[1] }.map{|e|  sprintf("%08b", e)  }.join(" | " )
=> "00011111 | 00001010 | 00011110 | 00000000 | 00001011"

この結果を、World以外の文字列でXORするともとに戻らない。

>> "Hello".each_byte.zip( "World".each_byte ).map{|e| e[0] ^ e[1] }.zip("abcdef".each_byte).map{|e| e[0] ^ e[1] }.map(&:chr).join
=> "~h}dn"

ただし、ただし、一部が一致すると。。。

>> "Hello".each_byte.zip( "World".each_byte ).map{|e| e[0] ^ e[1] }.zip("world".each_byte).map{|e| e[0] ^ e[1] }.map(&:chr).join
=> "hello"
>>

このように、一部が一致するとXORのランダムパッドでは暗号とは言えなくなる。

出てきた文字が正しいかわからない

>> "Hello".each_byte.zip( "World".each_byte ).map{|e| e[0] ^ e[1] }.zip("XYZaa".each_byte).map{|e| e[0] ^ e[1] }.map(&:chr).join
=> "GSDaj"

ここでは、暗号化に使う鍵に、「World」という文字列を採用しましたが、ランダムの使い捨てパッドである必要があります。

こうやって扱ってみると、ランダムパッドによる使い捨て暗号は、色々と問題があることがわかる。