I've seen a lot of confusion between encryption key size and block size. I feel like I completely understand the difference between the two, no need to explain what they are. But it's when put in practice that I feel like the two numbers get confused.

So let's look at the following php code...


...and assume the $iv has been created in a cryptographic secure way.

Question 1)

Is the MCRYPT_RIJNDAEL_128 defining the key size or the block size?

Question 2)

If we had set the key as:

$key={{eight cryptographically strong characters}};

Would the above code be an implementation of 64 bit encryption, because of the eight character key? Or would it be an implementation of 128 bit encryption because of the MCRYPT_RIJNDAEL_128?

Question 3)

Finally, if we instead do:

$key={{thirty-two cryptographically strong characters}};

Would that be an implementation of 256 bit encryption, or still 128 bit encryption? And if 128 bit, does that mean that a key longer than 128 bits gets trimmed somehow by the encryption algorithm?

  1. Key size. All Rijndale (aka. AES) cipher variants operate on the plaintext 128 bits at a time.
  2. No. Your 64 bits of key data would be expanded to a 128-bit key, either through zero-padding or through a key-derivation function. It won't be as strong as if you'd provided 128 bits of key data, but that's a different matter.
  3. No. Your 256 bits of key data will be reduced to a 128-bit key, either through truncation or through a key-derivation function. Since there's a 128-bit long key that produces the same encryption as your 256 bits of key data, you do not gain any security.
  • Correct answer is correct. Diving deeper into #2, you can think about it in terms of bruteforcing the input used to generate the 128 bit key. Guessing the input is easier than guessing the derived key. Similarly, if you have a 256 bit input used to derive a 128 bit key, its much easier to guess the derived key than it is to guess the input. Either way if it goes through a KDF, even a 64 bit input is hopeless to bruteforce. – Andrew Hoffman Oct 6 '14 at 14:40

Rijndael is a family of nine cryptographic algorithms, offering all combinations of block sizes and key sizes in the 128/192/256-bits set. The three algorithms with 128-bit blocks (and keys of 128, 192 and 256 bits) are collectively known as the AES. The six other combinations have been defined by the Rijndael authors, but were much less investigated by cryptographers since they were not part of the target of the AES competition.

What the MCRYPT_RIJNDAEL_* constants stand for is poorly documented, hence unclear. This man page about a library called "mcrypt" states that:

RIJNDAEL: Rijndael is a block cipher, designed by Joan Daemen and Vincent Rijmen, and was approved for the USA's NIST Advanced Encryption Standard, FIPS-197. The cipher has a variable block length and key length. Rijndael can be implemented very efficiently on a wide range of processors and in hardware. The design of Rijndael was strongly influenced by the design of the block cipher Square. There exist three versions of this algorithm, namely: RIJNDAEL-128 (the AES winner) , RIJNDAEL-192 , RIJNDAEL-256 The numerals 128, 192 and 256 stand for the length of the block size.

The last sentence would seem to imply that the "128" would be the block size, not the key length. However, this would be true only insofar as PHP's mcrypt module faithfully translates the naming conventions of the underlying mcrypt library, which is not a given.

In any case, the documentation for mcrypt_encrypt() states that:

The key with which the data will be encrypted. If it's smaller than the required keysize, it is padded with '\0'. It is better not to use ASCII strings for keys.

So, if you provide only 8 "strong characters", then these characters get somehow converted to bytes (Rijndael does not work on characters, it works on bytes) in some unspecified way, and if this does not yield sufficiently many bytes, then extra bytes of value 0 are added. What happens if there are too many bytes is not specified (truncation is plausible, but this is PHP -- anything can happen).

If you really want to use these functions, then you will have to make some tests, comparing encryption results with what another, better documented library would yield (in some language where bytes are bytes, e.g. C or Java). Among things to test are:

  • Block size and key length.
  • Conversion of a PHP string into bytes (notably in the presence of non-ASCII characters).
  • Behaviour on key length mismatch (padding, truncation,...).

Relying on such an under-documented function for security is akin to skydiving without verifying the parachute. If, at bag opening time, the parachute turns out to be your week's laundry, then you will have a few seconds to reflect, while free-falling amid an expanding cloud of unclean socks, that you really should have been more cautious.

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.