32 character PHP AES Key for mcrypt_encrypt

Consider the following PHP code:

<?php
$key = "1234567812345678";
$iv = "1234567812345678";
$data = "Test string";

$encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_128,
                            $key,
                            $data,
                            MCRYPT_MODE_CBC,
                            $iv);

print "Encoded1: " . base64_encode($encrypted) . "\n";

$key = "12345678123456781234567812345678";

$encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_128,
                            $key,
                            $data,
                            MCRYPT_MODE_CBC,
                            $iv);

print "Encoded2: " . base64_encode($encrypted) . "\n";

      

When run, this produces the output:

Encoded1: iz1qFlQJfs6Ycp+gcc2z4w==
Encoded2: n3D26h/m8CSH0CE+z6okkw==

      

Note that I stole the first bit of code from PHP Java AES CBC Encryption Different Results

Now - here's the question:

In the first case, the key that was passed was a 16 character string. If each of the individual characters were interpreted as an 8-bit number, this gives the 128-bit key size you would expect. Indeed, the Java code that the StackOverflow page I linked to above does exactly that and gets the same output as PHP.

In the second call mcrypt_encrypt

above, I doubled the key length. mcrypt_encrypt

accepts this happily, but produces a different encrypted output than the first case. Clearly, therefore, it considers it to be a different key - it does not accept, for example, only the first 128 bits and discards any past.

So how mcrypt_encrypt

does it handle an input key string to invoke the 128 bit key that the algorithm requires MCRYPT_RIJNDAEL_128

?

If it matters, the case I'm particularly interested in is when a 32 character string is passed as my second example - I need to create an appropriate decryption routine (in Java), so I need how the key is generated in this case. The page I quoted has perfectly good Java code (which works with all of my test cases). I am just missing the correct set of key bytes.

+3


source to share


1 answer


There are two important parameters for the Rijndael algorithm. There is a key size (128-bit, 192-bit and 256-bit) and then a block size (128-bit, 192-bit and 256-bit). 128

c MCRYPT_RIJNDAEL_128

refers to the block size. The key size is variable.

When you pass keys of different lengths to MCrypt, it will automatically select the appropriate key size, so you cannot and cannot install it. MCRYPT_RIJNDAEL_128

- AES (AES-128, AES-192, AES-256). MCRYPT_RIJNDAEL_192

and MCRYPT_RIJNDAEL_256

no longer AES.

If the Java code generated a corresponding result for a 128-bit key, then it will also produce a result for a 256-bit key.



MCrypt is a little weird. Prior to PHP version 5.6.0, it would take any key length, not just 128-bit, 192-bit, or 256-bit. The key will be filled with 0x00 bytes until the next valid key length.


Since Java does not support ZeroPadding out of the box, you must use the correct padding scheme, such as the PKCS # 5 / PKCS # 7 padding in PHP. This answer has a very good implementation.

+3


source







All Articles