# Simple encryption with PHP 5.5

I want to do simple encryption using PHP 5.5. By “simple” I mean I want to use native PHP functions. I have created this code that works, can it be improved? It's to encrypt/decrypt strings and binary files that are to be stored in a database and accessed via a website. Assume that it is done over SSL and that the password isn't hard-coded or stored anywhere on the web server.

Here's what I have (and it works). Is this secure? All the examples I found do not use PHP 5.5's hash_pbkdf2 function. I wanted a simple example that uses this.

Are there any downsides to using MCRYPT_MODE_CFB? Are 5000 iterations enough for PBKDF2 in this context?

// Check hash_pbkdf2 exists as it's not available < 5.5
if(function_exists('hash_pbkdf2') === false) {

// A fallback could be implemented here
exit('hash_pbkdf2() does not exist');

}

// Settings
$stringToEncrypt = 'This was encrypted'; // The plain text string to encrypt; binary files should be base64 encoded$encryptionPassword             = 'MyP@w0rd';                // The password; the only data that should be kept private
$pbkdf2Iterations = 5000; // More iterations = more secure, 1000 should be used as a minimum$pbkdf2HashAlgo                 = 'sha256';                    // 256-bit key size
$cipher = MCRYPT_RIJNDAEL_128; // Note: 128 refers to block size, not key size; MCRYPT_RIJNDAEL_128 is similar to 256-bit AES$blockMode                      = MCRYPT_MODE_CFB;            // CFB mode requires a random IV and does not require padding
$ivSource = MCRYPT_DEV_URANDOM; // URANDOM is faster than RANDOM in some environments // Create key using PBKDF2 hash$ivSize                         = mcrypt_get_iv_size($cipher,$blockMode);
$pbkdf2Salt = mcrypt_create_iv($ivSize, $ivSource);$key                            = hash_pbkdf2($pbkdf2HashAlgo,$encryptionPassword, $pbkdf2Salt,$pbkdf2Iterations);

// Pack the key into a binary hex string
$key = pack('H*',$key);

// Create random IV
$iv = mcrypt_create_iv($ivSize, $ivSource); // Encrypt the data$encryptedData                  = mcrypt_encrypt($cipher,$key, $stringToEncrypt,$blockMode, $iv); // Prepend the IV as it's needed for decryption$encryptedData                  = $iv .$encryptedData;

// Base64 encode it
$encryptedData = base64_encode($encryptedData);

// Decrypt
$decryptedData = base64_decode($encryptedData);

// Get the IV
$ivDecrypted = substr($decryptedData, 0, $ivSize); // Don't need to use mb_substr as it's hexadecimal // Get the encrypted data on its own$decryptedData                  = substr($decryptedData,$ivSize);

// Decrypted data
$decryptedData = mcrypt_decrypt($cipher, $key,$decryptedData, $blockMode,$ivDecrypted);

// Output for testing
echo "<p>stringToEncrypt: $stringToEncrypt</p>"; echo "<p>encryptionPassword:$encryptionPassword</p>";
echo "<p>pbkdf2Iterations: $pbkdf2Iterations</p>"; echo "<p>pbkdf2HashAlgo:$pbkdf2HashAlgo</p>";
echo "<p>ivSize: $ivSize</p>"; echo "<p>iv:$iv</p>";
echo "<p>pbkdf2Salt: $pbkdf2Salt</p>"; echo "<p>key:$key</p>";
echo "<p>encryptedData: $encryptedData</p>"; echo "<p>ivDecrypted:$ivDecrypted</p>";
echo "<p>decryptedData: \$decryptedData</p>";