Displaying posts written in

4月 2009

OpenSSL::Cipher::Cipher のパディング処理

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

一応実行結果も載せておく。見事に階段状になっていてちょっと面白い。
(続きを読む…)