Hudzilla.org - the homepage of Paul Hudson
Contents > Security concerns > Protecting your data Wish List | Report Bug | About Me ]

17.3.7     Changing encryption algorithm

This is NOT the latest copy of this book; click here for the latest version.

The first parameter to mcrypt_module_open() is the encryption algorithm you want to use. In the examples above, we used Rijndael, which is believed to be one of the most secure encryption algorithms. When the National Institute of Standards and Technology (NIST) in the US wanted to develop a new governmental standard for encryption, to be called the Advanced Encryption Standard (AES), they chose Rijndael for its encryption quality, speed of encryption, and ease of implementation.

However, there were two other excellent algorithms submitted as AES proposals, which are Serpent and Twofish. Serpent is arguably the most secure of the three, but its very conservative design leaves it running about three times slower than Rijndael. Twofish is a particularly interesting cipher because it was designed to make the encrypted data is random as possible, so it includes built-in plaintext whitening and other mechanisms that cause it run slower than AES but end with potentially more secure ciphertext.

PHP makes a selection of encryption algorithms available to you to use as the first parameter to mcrypt_module_open() - here are the key choices:

  • MCRYPT_3DES

  • MCRYPT_BLOWFISH

  • MCRYPT_DES

  • MCRYPT_RC6_128

  • MCRYPT_RC6_192

  • MCRYPT_RC6_256

  • MCRYPT_RIJNDAEL_128

  • MCRYPT_RIJNDAEL_192

  • MCRYPT_RIJNDAEL_256

  • MCRYPT_SERPENT_128

  • MCRYPT_SERPENT_192

  • MCRYPT_SERPENT_256

  • MCRYPT_TWOFISH_128

  • MCRYPT_TWOFISH_192

  • MCRYPT_TWOFISH_256

Of those, you should generally only use 3DES, Rijndael, Serpent, and Twofish. Rijndael, now known as AES, is the best choice more often than not for several reasons. AES is very fast for encrypting and decrypting, most (if not all) libraries will support it because it is the standard, and also the fact that most other people will be using it, including the US government. This last point is quite important, as if AES is cracked in the future (unlikely, but you never know!), your head will not be on the block, because it is the recommended standard encryption method. If you choose another method and that gets cracked, people might look to you asking why you did not choose the standard - not a good situation to be in.

Serpent is the best choice if you do not care about speed and just want the best possible encryption, however this is only for the most paranoid of people who have CPU cycles to burn. Twofish is a great algorithm that provides a blend of security and speed, and makes a good choice if you are not sure whether you want to favour speed or security. Finally, 3DES, despite being much, much less secure than AES, Twofish, or Serpent due to its age, is sometimes still the best algorithm to use because of its backwards compatibility.

Generally speaking, AES/Rijndael is your best choice, however it is worth experimenting with the others to find the one that gives you the most speed or security, depending on your criteria.

Author's Note: many of the encryption types end with 128, 192, and 256 - this is the block size in bits that you have available. The AES standard is strictly 128-bit, but Rijndael was developed to work with 128, 192, and 256 bits. You need not worry about block size - there is no compelling reason to choose between the three other than the fact that the standard is 128-bit.





<< 17.3.6 Symmetric decryption: mdecrypt_generic()   17.3.8 Changing block cipher mode >>
Table of Contents
Want to see this stuff in print? PHP in a Nutshell takes the core topics covered here, adds in thousands of edits from the editorial team and myself, and combines them to make an unbeatable reference for PHP programmers at all levels.



My latest book has hundreds more tips on how to use PHP, Apache, and MySQL, plus Perl, Python, shell scripts, performance tuning, and more!



Top-right shadow
 
Bottom-left shadow Bottom shadow

Comments from other readers
A PHP User - 07 Sep 2008

@ Glen.Boyer,

From "rolf at winmutt dot com" and "pixelchutes AT gmail DOT com" on www.php.net/mcrypt,

mysql AES_ENCRYPT() compatibly function for PHP :

function mysql_aes_encrypt($val,$ky) {
$mode=MCRYPT_MODE_ECB;
$enc=MCRYPT_RIJNDAEL_128;
$val=str_pad($val, (16*(floor(strlen($val) / 16)+(strlen($val) % 16==0?2:1))), chr(16-(strlen($val) % 16)));
return mcrypt_encrypt($enc, $ky, $val, $mode, mcrypt_create_iv( mcrypt_get_iv_size($enc, $mode), MCRYPT_DEV_URANDOM));
}

Please note that if the strlen($ky)>16 then this function will not be compatible.

For those looking for a mysql_aes_decrypt, I created this method, referencing rolf's aes_encrypt below. Since the aes_encrypt right-pads N * blocksize with any chr( 0 ) to chr( 16 ) (random based on the input string length) we first decrypt the text, then RTrim chr(0 .. 16) depending on its trailing ord() value.

mysql AES_DECRYPT() compatibly function for PHP :

<?
function mysql_aes_decrypt( $val, $ky )
{
$mode = MCRYPT_MODE_ECB;
$enc = MCRYPT_RIJNDAEL_128;
$dec = @mcrypt_decrypt($enc, $ky, $val, $mode, @mcrypt_create_iv( @mcrypt_get_iv_size($enc, $mode), MCRYPT_DEV_URANDOM ) );
return rtrim( $dec, ( ( ord(substr( $dec, strlen( $dec )-1, 1 )) >= 0 and ord(substr( $dec, strlen( $dec )-1, 1 ) ) <= 16 ) ? chr(ord(substr( $dec, strlen( $dec )-1, 1 ))): null) );
}
?>

Please note that if the strlen($ky)>16 then this function will not be compatible.

A PHP User - 07 Sep 2008

how about blowfish? which do you think would be better...

well i suppose it wont hurt as i am using multiple encryption with a key separate from the users.

its just that i want to know which is better, blowfish or twofish?

A PHP User - 07 Sep 2008

I want to know the PHP code of cymmetric API

A PHP User - 07 Sep 2008

From wikipedia: http://en.wikipedia.org/wiki/Advanced_Encryption_Standard

In June 2003, the US Government announced that AES may be used for classified information:

"The design and strength of all key lengths of the AES algorithm (i.e., 128, 192 and 256) are sufficient to protect classified information up to the SECRET level. TOP SECRET information will require use of either the 192 or 256 key lengths. The implementation of AES in products intended to protect national security systems and/or information must be reviewed and certified by NSA prior to their acquisition and use."

http://www.cnss.gov/Assets/pdf/cnssp_15_fs.pdf

Also:

Key sizes of 128, 160, 192, 224, and 256 bits are supported by the Rijndael algorithm, but only the 128, 192, and 256 bit key sizes are specified in the AES standard.

A PHP User - 07 Sep 2008

By standard you mean FIPS 197 (which is publish by the US govt) not to be confused by IETF standards.

That said, just because one US government entity ratified a crypto method for use within the US govt and anyone contract to the US govt needs to use AES, that doesn't stop other people using RIJNDAEL 256 as it should be stronger then AES.

A PHP User - 07 Sep 2008

AES is not restricted to 128 bit keys.

There are MANY compelling reasons to use key strengths higher than 128 -- i.e. you don't want somebody with a large (but not overly obscene) computing resource to break your key in a few weeks.

This book has so many glaring errors and omissions its painful to flip through.

Glen.Boyer@pacificevents.com - 07 Sep 2008

This is more of a question, and you may not know the answer, but I'll ask just in case.

Using PHP/AES/Rijndael128 vs MySQL AES_ENCRYPT, do you know a way to make these match?

Currently I'm having to make a command decision whether to have PHP do the encrypting vs MySQL doing it. At present using PHP & MCrypt I'm unable to get the same results. I'm wondering if there is some other codes or salt or something that one is doing verses the other.

Any Idea?

Potentially one or the other (PHP or MySQL) may or may not be replaced in the future. It would be nice if both systems code encrypt and decrypt the other.

A PHP User - 07 Sep 2008

Why use MCRYPT_RIJNDAEL_256 in the example in the last section, when the standard and recommended is MCRYPT_RIJNDAEL_128?



Add comment
Please note that by posting a comment here you are committing it to the public domain. This is important so that others can make use of your code themselves, and also so that I can incorporate helpful notes directly into the main text. Comments are limited to 2000 characters in length.

If you are reporting an error in the content, please tell me directly.

Your name/email address:
Your comment:
 
Now, in order to verify that you're a real person, please answer this simple question: what is six plus three?
The answer is:
(please write in
numbers, eg 19)


Top-right shadow
 
Bottom-left shadow Bottom shadow