Using PHP mcrypt with Rijndael / AES

I am trying to encrypt some text messages using mcrypt from php and Rijndael encryption, but I'm not sure about MCRYPT_MODE_modename (according to the PHP manual they are available "ecb", "cbc", "cfb", "ofb" "," nofb "or" stream "but I read that there are actually a few more). I have no idea what they are doing and how to use them.

I read two things: ECB mode should not be used and MCRYPT_RAND. They did not explain why. For ECB mode, I assume that it always generates the same encrypted output for the same plain text (maybe this can be used for attack), I don't know about MCRYPT_RAND (@azz is mentioned here ).

My question is which mode mcrypt should be used, and it would be great to see an example of using PHP code, because all the examples that I found use ECB. The lines I'm trying to encrypt will contain only ascii text and a variable length of not more than 500 characters.

+8
php cryptography encryption aes mcrypt
source share
2 answers

ecb is the simplest and has drawbacks, so it is not recommended ( http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation ). cbc is considered significantly stronger than ecb. Some of the others may be even stronger than cbc, but they are all flow-related, so cbc should suit your needs.

From ... http://us.php.net/manual/en/mcrypt.constants.php ...

  • MCRYPT_MODE_ECB (electronic code book) is suitable for random data such as encryption of other keys. Since the data are short and random, the ECB's shortcomings have a beneficial negative effect.
  • MCRYPT_MODE_CBC (encryption block chain) is particularly suitable for file encryption, where security is significantly increased over ECB.
  • MCRYPT_MODE_CFB (encryption feedback) is the best mode for encrypting byte streams where single bytes should be encrypted.
  • MCRYPT_MODE_OFB (8-bit output feedback) is comparable to CFB, but can be used in applications where error propagation cannot be tolerated. This is unsafe (because it works in 8-bit mode), so it is not recommended to use it.
  • MCRYPT_MODE_NOFB (output feedback, in nbit) is comparable to OFB, but more secure since it works with the block size of the algorithm.
  • MCRYPT_MODE_STREAM is an optional mode for enabling some stream algorithms, such as "WAKE" or "RC4".

I donโ€™t know why MCRYPT_RAND is recommended, but maybe because the random number generator of the system on many systems is not considered truly random. There are only two alternatives, and they may not be available depending on your system and PHP version. From ... http://php.net/manual/en/function.mcrypt-create-iv.php ...

  • Source IV can be MCRYPT_RAND (system random number generator), MCRYPT_DEV_RANDOM (read data from / dev / random) and MCRYPT_DEV_URANDOM (read data from / dev / urandom). Prior to 5.3.0, MCRYPT_RAND was the only one supported on Windows.

The code below is just a sample. It works, but I canโ€™t confirm its strength.

 <? php

 // Test code

     $ objEncManager = new DataEncryptor ();

     $ sensitiveData = "7890";
     echo "Raw Data: _".  $ sensitiveData.  "_ <br> <br>";

     $ encryptedData = $ objEncManager-> mcryptEncryptString ($ sensitiveData);
     echo "Enc Data: _".  $ encryptedData.  "_ <br> <br>";
     echo "Enc Data length:".  strlen ($ encryptedData).  "<br> <br>";

     $ decryptedData = $ objEncManager-> mcryptDecryptString ($ encryptedData, $ objEncManager-> lastIv);
     echo "D-enc Data: _".  $ decryptedData.  "_ <br> <br>";

     echo "IV: _".  $ objEncManager-> lastIv.  "_ <br> <br>";


 / *
  * Note: These functions do not accurately handle cases where the data 
  * being encrypted have trailing whitespace so the data
  * encrypted by them must not have any.  Leading whitespace is okay.
  *  
  * Note: If your data needs to be passed through a non-binary safe medium you should
  * base64_encode it but this makes the data about 33% larger.
  * 
  * Note: The decryption IV must be the same as the encryption IV so the encryption
  * IV must be stored or transmitted with the encrypted data.
  * From (http://php.net/manual/en/function.mcrypt-create-iv.php) ... 
  * "The IV is only meant to give an alternative seed to the encryption routines. 
  * This IV does not need to be secret at all, though it can be desirable. 
  * You even can send it along with your ciphertext without losing security. "
  * 
  * Note: These methods don't do any error checking on the success of the various mcrypt functions
  * /
 class DataEncryptor
 {
     const MY_MCRYPT_CIPHER = MCRYPT_RIJNDAEL_256;
     const MY_MCRYPT_MODE = MCRYPT_MODE_CBC;
     const MY_MCRYPT_KEY_STRING = "1234567890-abcDEFGHUzyxwvutsrqpo";  // This should be a random string, recommended 32 bytes

     public $ lastIv = '';


     public function __construct ()
     {
         // do nothing
     }


     / **
      * Accepts a plaintext string and returns the encrypted version
      * /
     public function mcryptEncryptString ($ stringToEncrypt, $ base64encoded = true)
     {
         // Set the initialization vector
             $ iv_size = mcrypt_get_iv_size (self :: MY_MCRYPT_CIPHER, self :: MY_MCRYPT_MODE);
             $ iv = mcrypt_create_iv ($ iv_size, MCRYPT_RAND);
             $ this-> lastIv = $ iv;

         // Encrypt the data
             $ encryptedData = mcrypt_encrypt (self :: MY_MCRYPT_CIPHER, self :: MY_MCRYPT_KEY_STRING, $ stringToEncrypt, self :: MY_MCRYPT_MODE, $ iv);

         // Data may need to be passed through a non-binary safe medium so base64_encode it if necessary.  (makes data about 33% larger)
             if ($ base64encoded) {
                 $ encryptedData = base64_encode ($ encryptedData);
                 $ this-> lastIv = base64_encode ($ iv);
             } else {
                 $ this-> lastIv = $ iv;
             }

         // Return the encrypted data
             return $ encryptedData;
     }


     / **
      * Accepts a plaintext string and returns the encrypted version
      * /
     public function mcryptDecryptString ($ stringToDecrypt, $ iv, $ base64encoded = true)
     {
         // Note: the decryption IV must be the same as the encryption IV so the encryption IV must be stored during encryption

         // The data may have been base64_encoded so decode it if necessary (must come before the decrypt)
             if ($ base64encoded) {
                 $ stringToDecrypt = base64_decode ($ stringToDecrypt);
                 $ iv = base64_decode ($ iv);
             }

         // Decrypt the data
             $ decryptedData = mcrypt_decrypt (self :: MY_MCRYPT_CIPHER, self :: MY_MCRYPT_KEY_STRING, $ stringToDecrypt, self :: MY_MCRYPT_MODE, $ iv);

         // Return the decrypted data
             return rtrim ($ decryptedData);  // the rtrim is needed to remove padding added during encryption
     }


 }
 ?>
+16
source share

ECB mode is not safe because it does not introduce randomness into encrypted data. This basically means that you will see the same input patterns on the output (i.e. See Image here , this is the โ€œencryptedโ€ version of Tux, the Linux logo).

MT_RAND is not considered secure because it uses a random number generator for the operating system (the rand() function for PHP).

For cryptography purposes, it is better to use MCRYPT_DEV_RANDOM (read data from / dev / random) or MCRYPT_DEV_URANDOM (read data from / dev / urandom).

The most commonly used and secure encryption modes available in Mcrypt are CBC and CTR modes and are suitable for general use. It is always better to use encryption + authentication (i.e., encryption and then authentication using HMAC). For example, CBC mode without authentication depends on "Attack in addition to Oracle . "

+2
source share

All Articles