Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

proper PHP mcrypt encryption methods?

Tags:

php

mcrypt

Ok, I have tried to create my own encryption/decryption methods using PHP mcrypt, and when I posted them a while back some called them "trash". They were mentioning things about "Initialization Vectors" and such. Basically, how can I make these cryptography methods better:

function encrypt($key, $data){
    $encrypted_data = mcrypt_cbc(MCRYPT_RIJNDAEL_192, $key, $data, MCRYPT_ENCRYPT);
    return base64_encode($encrypted_data);
}

function decrypt($key, $encryptedData){
    $dec = base64_decode($encryptedData);
    $decrypt = mcrypt_cbc(MCRYPT_RIJNDAEL_192, $key, $dec, MCRYPT_DECRYPT);
    return trim($decrypt);
}

I want these to work the best they can except I am a duck in a brand new world when it comes to mcrypt, any suggestions are welcome, thanks!

like image 800
nkcmr Avatar asked Sep 16 '11 18:09

nkcmr


People also ask

Can PHP be used to encrypt data?

PHP can assist you in this with several extensions, such as OpenSSL and Sodium, covering a wide variety of encryption algorithms. The script encrypts the data before inserting it into the database, and decrypts it when retrieving. See the references for further examples of how encryption works.

Is PHP mcrypt deprecated?

ext/mcrypt ¶The mcrypt extension has been abandonware for nearly a decade now, and was also fairly complex to use. It has therefore been deprecated in favour of OpenSSL, where it will be removed from the core and into PECL in PHP 7.2.

What encryption techniques are there in PHP?

Methods of PHP Encryption At the moment, developers can opt for several encryption methods, common being hashing, secret key encryption, and envelope encryption method.

Which encryption is best for PHP?

Secret key encryption (or symmetric encryption as it's also known) uses a single key to both encrypt and decrypt data. In the past PHP relied on mcrypt and openssl for secret key encryption. PHP 7.2 introduced Sodium, which is more modern and widely considered more secure.


2 Answers

Here is a snippet of the mcrypt functions I use. They use mcrypt_generic and mdecrypt_generic, which should be used according to the PHP manual.

function encrypt($key, $data){
    $b = mcrypt_get_block_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
    $enc = mcrypt_module_open(MCRYPT_RIJNDAEL_256, '', MCRYPT_MODE_CBC, '');
    $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($enc), MCRYPT_DEV_URANDOM);
    mcrypt_generic_init($enc, md5($key), $iv);

    // PKCS7 Padding from: https://gist.github.com/1077723
    $dataPad = $b-(strlen($data)%$b);
    $data .= str_repeat(chr($dataPad), $dataPad);

    $encrypted_data = mcrypt_generic($enc, $data);

    mcrypt_generic_deinit($enc);
    mcrypt_module_close($enc);

    return array(
        'data' => base64_encode($encrypted_data),
        'iv' => base64_encode($iv)
    );
}

function decrypt($key, $iv, $encryptedData){
    $iv = base64_decode($iv);
    $enc = mcrypt_module_open(MCRYPT_RIJNDAEL_256, '', MCRYPT_MODE_CBC, '');
    mcrypt_generic_init($enc, md5($key), $iv);

    $encryptedData = base64_decode($encryptedData);
    $data = mdecrypt_generic($enc, $encryptedData);
    mcrypt_generic_deinit($enc);
    mcrypt_module_close($enc);

    // PKCS7 Padding from: https://gist.github.com/1077723
    $dataPad = ord($data[strlen($data)-1]);

    return substr($data, 0, -$dataPad);
}

I don't know much about mcrypt either, so I just kinda hacked these together. I md5 the key so it's always 32 characters (the max key length), and I randomly calculate an "Initialization Vector".

Using PKCS7 Padding is better because you can have strings that end in white space (as trim would remove that), also the encryption is more efficient when the string is a certain length.

I'm using AES 256 (MCRYPT_RIJNDAEL_256) here, but AES 192 (MCRYPT_RIJNDAEL_192) would work too.

Demo: http://ideone.com/WA5Tk

like image 110
Rocket Hazmat Avatar answered Oct 10 '22 22:10

Rocket Hazmat


You can create an iv with mcrypt_create_iv(), using the appropriate size for your encryption mode.

$size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_192, MCRYPT_MODE_CBC);
$iv = mcrypt_create_iv($size, MCRYPT_DEV_RANDOM);

Then pass it to mcrypt_cbc() as the optional 5th parameter. The only changes I've made here to your original functions are to pass in $iv:

function encrypt($key, $data, $iv){
    $encrypted_data = mcrypt_cbc(MCRYPT_RIJNDAEL_192, $key, $data, MCRYPT_ENCRYPT, $iv);
    return base64_encode($encrypted_data);
}

function decrypt($key, $encryptedData, $iv){
    $dec = base64_decode($encryptedData);
    $decrypt = mcrypt_cbc(MCRYPT_RIJNDAEL_192, $key, $dec, MCRYPT_DECRYPT, $iv);
    return trim($decrypt);
}
like image 31
Michael Berkowski Avatar answered Oct 11 '22 00:10

Michael Berkowski