OpenSSL::Cipher::Cipher#padding= でパディング処理の有無を制御できる。では実際にどのようなパディング処理が行われているのだろう?
暗号化時にはパディングを有効にして、復号時に無効にすれば確認できる。
# Ruby 1.8.7 or 1.9 require 'openssl' def enc_dec_base(operation) password = 'fixed password' lambda do | cipher, data, padding | c = OpenSSL::Cipher::Cipher.new(cipher) c.send(operation) c.padding = padding c.pkcs5_keyivgen(password) c.update(data) + c.final end end
encrypt = enc_dec_base(:encrypt) decrypt = enc_dec_base(:decrypt) cipher = 'aes-256-cbc' msg = 'ABCDEFGHIJKLMNOP' # 16bytes = AES block size (1..msg.size).each do |len| plain = msg[0, len] encrypted = encrypt[cipher, plain, 1] decrypted = decrypt[cipher, encrypted, 0] # disable padding puts "original message: #{plain}" p plain.bytes.to_a p decrypted.bytes.to_a puts end
結果、PKCS#5 の PBES1, PBES2 と同じく RFC 1423 で定義されたパディング処理を行っていることが分かった。このパディングアルゴリズムは一般には PKCS#5 Padding などと呼ばれているらしい。
PHP の mcrypt ライブラリと相互運用する場合は、PHP 側で適切に処理する必要がある。PHP Manual の User Contributed Notes に実装例を見つけた:duerra_NOT_THIS_ at pushitlive dot net。
一応実行結果も載せておく。見事に階段状になっていてちょっと面白い。
(続きを読む…)