I have two different crypto libraries I created, one is in java and uses the standard built-in java crypto libraries.

The other uses openssl and has been wrapped in java through the JNI.

I'm currently replacing the default java library code with the openssl library code, and verifying the encryptions against each other to make sure nothing breaks for my end user. I'm curious, because java is only guaranteed to support 128 bit keys using its implementation of PBKDF2, so I'm using AES CBC 128 with java. I had originally coded for AES CBC 256 in openssl, not thinking.

What I'm curious about is this: When I input a 256 bit key into java's AES CBC 128, I got the same output as I did for openssl's AES CBC 256. When I input a 128 bit key into AES CBC 128, I got a different output than when I input the same key into openssl's AES CBC 256. (I used the same 16 byte IV across all trials)

I assume the two different encryption schemes would generate completely different results, so I'm confused as to why this is happening. I thought I had a better understanding of the cipher than it appears I actually do.

Apologies if this is a painfully obvious result, I'm still somewhat new to crypto.

  • 1
    As noted in the javadoc, java implementations (e.g. oracles implementation) are required to support AES-128/CBC. It does not state that AES-192 and AES-256 may not be implemented. So if you pass a 256 bit key to a cipher obtained using javax.crypto.Cipher.getInstance("AES/CBC/PKCS5Padding") it will doe AES-256 if supported, otherwise throw an exception. – marstato Jan 1 '16 at 23:18

"AES-128" means "AES used with a 128-bit key". "AES-256" means "AES used with a 256-bit key". By definition, you should use a 128-bit key with AES-128, and a 256-bit key with AES-256.

What happens when you give a 256-bit key to AES-128, or a 128-bit key to AES-256 ? By all rights, it should blow up in your face. However, some implementations are more tolerant. Some implementations will automatically adjust to the provided key size; in that case, when you put a 256-bit key into AES-128, the AES-128 implementation morphs into an AES-256 implementation (AES-128, AES-192 and AES-256 are very similar internally; they differ only by the number of rounds; so it makes sense that they share most of their code). Some other implementations will ignore your "key length" and grab the bytes they believe they need; e.g. you give a 256-bit key to an AES-128, and only the first 128 bits get used. Since you are doing things out of specification, this is the realm of the bug, and anything goes.

  • 1
    For all recent Java if you call Cipher.getInstance("AES") or the complete forms AES/mode/padding it returns an object that accepts (by calling .init) a 128, 192, or 256-bit key. In Java8 only (so far) you can instantiate AES_128 or AES_192 or AES_256 or any of those with /mode/padding and those objects will only accept a key of the specified size. For Oracle builds, all symmetric ciphers including these using a key over 128 bits requires you (also) install the "Unlimited Strength Policy Files". ... – dave_thompson_085 Jan 2 '16 at 17:55
  • ... In contrast OpenSSL EVP-wrapped ciphers like aes-128-cbc take the needed number of bytes at the pointer you pass; in C nothing ensures the pointer actually points at the correct amount of data. (The same for IV -- except for stream cipher that has no IV.) The low-level AES_set_{en,de}crypt_key explicitly specifies the length in the call and handles the three AES options. – dave_thompson_085 Jan 2 '16 at 18:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.