I'm trying to match the AES encryption from the java implementation of BouncyCastle with Ruby. Somehow, even with the same key, IV and payload, I can't seem to get the same results in both languages.
In this example, I'm using ruby to generate the key and IV, and then reuse this key and IV in the java code.
Can anyone spot what's wrong?
Here's the ruby code:
require 'openssl'
cipher = OpenSSL::Cipher::AES.new(128, "CFB")
cipher.encrypt
payload = "\x01\x02\x03\x04".b
puts "key"
puts cipher.random_key.unpack("H*")
puts "iv"
puts cipher.random_iv.unpack("H*")
puts (cipher.update(payload) + cipher.final).unpack("H*")
And its output:
key
19900205760f9b9696b34cacdbf0189d
iv
b549f3bb806c4bce9c949f61185f2c38
303dc6e6
And the (not so) corresponding java code
byte[] key = hexStringToByteArray("19900205760f9b9696b34cacdbf0189d");
byte[] iv = hexStringToByteArray("b549f3bb806c4bce9c949f61185f2c38");
byte[] payload = new byte[] { 1, 2, 3, 4};
AESEngine aesEngine = new AESEngine();
CFBBlockCipher cipher = new CFBBlockCipher(aesEngine, 8);
ParametersWithIV params = new ParametersWithIV(new KeyParameter(key), iv);
BufferedBlockCipher bbc = new BufferedBlockCipher(cipher);
bbc.init(true, params);
byte[] output = new byte[payload.length];
int result = bbc.processBytes(payload, 0, payload.length, output, 0);
bbc.doFinal(output, result);
System.out.println("With BC: " + bytesToHex(output));
The java result is
305F1C09
For any payload, the first byte is always identical with both implementations, but then the rest varies. Could it be that the cipher feedback loop is not working the same way?
Edit: As James indicated in the comments, it's a problem of block size. In the code above, ruby seems to be using a default of 128 bit block size, whereas the java code uses 8 bit block. In my case, I must match the ruby code to java, so I now need to find a way to use 8 bit block size with ruby.
I'm dry. Any idea here?
So as James indicated, the block size was wrong on ruby. I should use 8 bit block size for the CFB, but instead was using the default 128 bit.
This solved it:
cipher = OpenSSL::Cipher.new("AES-128-CFB8")