jruby-openssl icon indicating copy to clipboard operation
jruby-openssl copied to clipboard

cipher.update and cipher.final JRuby vs MRI behavior different

Open shibz opened this issue 6 years ago • 0 comments

cipher.update and cipher.final have different behavior in JRuby vs MRI for block ciphers when data is added in KEY_LENGTH sized chunks.

require 'openssl'
require 'securerandom'

KEY_LENGTH = 16

cipher = OpenSSL::Cipher.new("AES-128-CBC")
cipher.encrypt
cipher.key = SecureRandom.random_bytes(KEY_LENGTH)

puts cipher.update(SecureRandom.random_bytes(KEY_LENGTH)).length

# MRI = 16
# JRuby = 0

puts cipher.final.length

# MRI = 16
# JRuby = 32

In MRI Ruby, a block of ciphertext is returned as soon as an entire block of data (KEY_LENGTH bytes) has been provided to the cipher. In JRuby, that block of ciphertext is not returned until one additional byte is added to the cipher (for a total of KEY_LENGTH + 1 bytes) via cipher.update.

This produces undesired results in situations where the cipher.final method should be optional because the last block (with PKCS#7 padding) is not desired. For example: https://github.com/SmallLars/openssl-cmac/pull/3

shibz avatar Jul 12 '19 17:07 shibz