27 Sep 2009

Initialization Vector Length in MRI Ruby versus JRuby

When using OpenSSL encryption in standard Ruby, the length of an initialization vector (IV) can apparently be as large as you want it to be as long as it is at least the minimum size. This is odd. This can also cause trouble when switching over to JRuby. JRuby appear to be much pickier about IV length.

This works in MRI but not in JRuby:

  unencrypted_data = "test"

  des = OpenSSL::Cipher::Cipher.new("des-ede3-cbc")
  des.encrypt
  des.key = '0123456789abcdef01234567890'

  des.iv = "ed87acdcca419954edccb736f7dc77a74f5ac8dfe3861c3d5f77248e21592131a5423d63ff91f07956ce1aa386f8359931b5" # 100 characters
  encrypted_data = des.update(unencrypted_data) + des.final

  puts encrypted_data

JRuby gives you this very helpful message:
@ruby_string_encryption.rb:27:in `encrypt': No message available (OpenSSL::Cipher::CipherError)
from ruby_string_encryption.rb:37@

Change the IV to 8 characters and everything works fine.

Update 10/14/2009 The code that I originally posted was incorrect. I have updated it. Also I opened a ticket for this issue.

If you are looking for what size an initialization vector should be check out my post on encrypting a string with Ruby.