Search code examples
phplinuxencryptioncryptographyphp-openssl

PHP encryption not working on server


I'm trying to store encrypted cookies in a PHP app and have implemented 2 different encryption libraries in attempts to get this to work.

Both implementations, when deployed to the server, are generating fatal exceptions when calling my encryption function. On my local dev env, however, both encryption implementations are working successfully.

My open_ssl implementation code (works on localhost, does not work on remote server):

set_encrypted_cookie("foo","my_cookie_name");

function set_encrypted_cookie($msg,$name){
    $key = '0123456qwerty'; // Key is stored externally but defined locally for debugging

    $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);

    $encryptedStr = openssl_encrypt($msg, 'aes-256-cbc', $key, OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING, $iv);

    setcookie($name,$encryptedStr,0,'/');
}

Any thoughts on why the server might be not allowing the openssl_encrypt() func to execute?


Solution

  • openssl_encrypt() returns raw binary, you should base64_encode() before storing in a cookie.

    Before you do that, a couple of things you can do to improve your cryptography protocol:

    1. Use MCRYPT_DEV_URANDOM, not MCRYPT_RAND.
    2. Store your IV with your ciphertext (before base64_encode()ing it), so you can use the same IV when decrypting.
    3. Encrypt then MAC.

    The last link has two functions, setLessUnsafeCookie() and getLessUnsafeCookie(), that you can use as a drop-in on PHP 5.6.x.

    There are still two more things to do to make it safe to use:

    1. Use HKDF to split the key into an encryption key and a decryption key.
    2. Use PKCS7 padding on the plaintext.

    (If you want to go for maximum security, you can use libsodium instead of openssl.) Also, don't use mcrypt.