Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

I am trying to add encryption functionality to a PHP script, modeled on an existing C# application.

The C# app uses the Rijndael algorithm with default constructor. From this I am able to determine that it has a key size of 256 and a block size of 128.

I am unsure about selecting the appropriate cipher for php's mcrypt function. The list of ciphers show:

MCRYPT_RIJNDAEL_128
MCRYPT_RIJNDAEL_192
MCRYPT_RIJNDAEL_256

But I am not sure if the trailing number is referring to key length, the number of bits used in the encryption or if those are one in the same.

What cipher should I use to match the existing functionality? When I try 256 I get the error "The IV parameter must be as long as the blocksize". If I try 128, the resulting keys don't match (though I suspect this is still an error with something other than cipher selection.)

Sorry for the basic nature of the question, it would help to have some layman explanation.

share|improve this question
    
If anyone is interested, this relates to my question on SO: stackoverflow.com/questions/9011635/… –  JYelton Jan 26 '12 at 18:46

1 Answer 1

up vote 2 down vote accepted

Rijndael is a versatile block cipher which can work with blocks of size 128, 192 or 256 bits, and with keys of 128, 192 or 256 bits. All nine combinations are possible.

In 2001, as part of an open competition which went on for three years, Rijndael was chosen to become the US federal "Advanced Encryption Standard", aka the AES; but only with a block size of 128 bits. So there are exactly three versions of the AES, all with a 128-bit block size, and with keys of 128, 192 or 256 bits.

Therefore, while Rijndael formally supports blocks of 192 or 256 bits, it is very rarely used that way; it is thus highly plausible that MCRYPT_RIJNDAEL_256 actually means "Rijndael with a 128-bit block size, and 256-bit key (aka 'AES-256')".

The Initialization Vector (IV) is a piece of data which must be used as parameter to the encryption mode; in your code, you appear to use CBC, so the IV must have the same length then the block size (128 bits, aka 16 bytes).

I see that you are trying to use PBKDF1. This is an old key derivation function which is limited in several ways, including its inability to output more than 20 bytes. You will have a hard time getting 32 bytes of key and 16 bytes of IV ouf of PBKDF1... I suggest you switch to PBKDF2, also defined in RFC 2898, implemented in C# by Rfc2898DeriveBytes, and which can output as many bytes as you need.

Note that PBKDF2 (and PBKDF1, for that matter) use some configurable parameters, such as an "iteration count", or the name of the underlying hash function. You have to take care to use the exact same parameters in the PHP code and in the C# code, otherwise you will not obtain the same keys and IV, and decryption will fail.

share|improve this answer
    
This is extremely helpful. I am curious what the C# code is doing when GetBytes() is called; you are right in that the PHP code I am not getting enough bytes. Unfortunately I can't change to Rfc2898DeriveBytes in the C# app due to having a lot of stored hashes that I assume rely on the existing method. –  JYelton Jan 26 '12 at 19:56
    
Hi Thomas, I came to the same conclusion about the blocksize of Rijndael and the KDF for the question on StackOverflow. However, MickeySoft uses an "extension of the PBKDF1" which seems to return as many bytes as requested. Would you know what they have brewed up? It does not seem to be documented anywhere. –  owlstead Jan 26 '12 at 20:20
    
Never mind, got it, it's explained here, and it is certainly a MickeySoft algorithm. –  owlstead Jan 26 '12 at 20:42

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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