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

一応実行結果も載せておく。見事に階段状になっていてちょっと面白い。

original message: A
[65]
[65, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15]

original message: AB
[65, 66]
[65, 66, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14]

original message: ABC
[65, 66, 67]
[65, 66, 67, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13]

original message: ABCD
[65, 66, 67, 68]
[65, 66, 67, 68, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12]

original message: ABCDE
[65, 66, 67, 68, 69]
[65, 66, 67, 68, 69, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11]

original message: ABCDEF
[65, 66, 67, 68, 69, 70]
[65, 66, 67, 68, 69, 70, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10]

original message: ABCDEFG
[65, 66, 67, 68, 69, 70, 71]
[65, 66, 67, 68, 69, 70, 71, 9, 9, 9, 9, 9, 9, 9, 9, 9]

original message: ABCDEFGH
[65, 66, 67, 68, 69, 70, 71, 72]
[65, 66, 67, 68, 69, 70, 71, 72, 8, 8, 8, 8, 8, 8, 8, 8]

original message: ABCDEFGHI
[65, 66, 67, 68, 69, 70, 71, 72, 73]
[65, 66, 67, 68, 69, 70, 71, 72, 73, 7, 7, 7, 7, 7, 7, 7]

original message: ABCDEFGHIJ
[65, 66, 67, 68, 69, 70, 71, 72, 73, 74]
[65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 6, 6, 6, 6, 6, 6]

original message: ABCDEFGHIJK
[65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75]
[65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 5, 5, 5, 5, 5]

original message: ABCDEFGHIJKL
[65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76]
[65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 4, 4, 4, 4]

original message: ABCDEFGHIJKLM
[65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77]
[65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 3, 3, 3]

original message: ABCDEFGHIJKLMN
[65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78]
[65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 2, 2]

original message: ABCDEFGHIJKLMNO
[65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79]
[65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 1]

original message: ABCDEFGHIJKLMNOP
[65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80]
[65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16]

Leave a Reply