phpsecurityencryptioncryptographyencryption-symmetric

How do you Encrypt and Decrypt a PHP String?


What I mean is:

Original String + Salt or Key --> Encrypted String
Encrypted String + Salt or Key --> Decrypted (Original String)

Maybe something like:

"hello world!" + "ABCD1234" --> Encrypt --> "2a2ffa8f13220befbe30819047e23b2c" (may be, for e.g)
"2a2ffa8f13220befbe30819047e23b2c" --> Decrypt with "ABCD1234" --> "hello world!"

Attempted to use Crypt_Blowfish, but it didn't work for me.


Solution

  • Updated

    PHP 7 ready version. It uses openssl_encrypt function from PHP OpenSSL Library.

    class Openssl_EncryptDecrypt {
        function encrypt ($pure_string, $encryption_key) {
            $cipher     = 'AES-256-CBC';
            $options    = OPENSSL_RAW_DATA;
            $hash_algo  = 'sha256';
            $sha2len    = 32;
            $ivlen = openssl_cipher_iv_length($cipher);
            $iv = openssl_random_pseudo_bytes($ivlen);
            $ciphertext_raw = openssl_encrypt($pure_string, $cipher, $encryption_key, $options, $iv);
            $hmac = hash_hmac($hash_algo, $ciphertext_raw, $encryption_key, true);
            return $iv.$hmac.$ciphertext_raw;
        }
        function decrypt ($encrypted_string, $encryption_key) {
            $cipher     = 'AES-256-CBC';
            $options    = OPENSSL_RAW_DATA;
            $hash_algo  = 'sha256';
            $sha2len    = 32;
            $ivlen = openssl_cipher_iv_length($cipher);
            $iv = substr($encrypted_string, 0, $ivlen);
            $hmac = substr($encrypted_string, $ivlen, $sha2len);
            $ciphertext_raw = substr($encrypted_string, $ivlen+$sha2len);
            $original_plaintext = openssl_decrypt($ciphertext_raw, $cipher, $encryption_key, $options, $iv);
            $calcmac = hash_hmac($hash_algo, $ciphertext_raw, $encryption_key, true);
            if(function_exists('hash_equals')) {
                if (hash_equals($hmac, $calcmac)) return $original_plaintext;
            } else {
                if ($this->hash_equals_custom($hmac, $calcmac)) return $original_plaintext;
            }
        }
        /**
         * (Optional)
         * hash_equals() function polyfilling.
         * PHP 5.6+ timing attack safe comparison
         */
        function hash_equals_custom($knownString, $userString) {
            if (function_exists('mb_strlen')) {
                $kLen = mb_strlen($knownString, '8bit');
                $uLen = mb_strlen($userString, '8bit');
            } else {
                $kLen = strlen($knownString);
                $uLen = strlen($userString);
            }
            if ($kLen !== $uLen) {
                return false;
            }
            $result = 0;
            for ($i = 0; $i < $kLen; $i++) {
                $result |= (ord($knownString[$i]) ^ ord($userString[$i]));
            }
            return 0 === $result;
        }
    }
    
    define('ENCRYPTION_KEY', '__^%&Q@$&*!@#$%^&*^__');
    $string = "This is the original string!";
    
    $OpensslEncryption = new Openssl_EncryptDecrypt;
    $encrypted = $OpensslEncryption->encrypt($string, ENCRYPTION_KEY);
    $decrypted = $OpensslEncryption->decrypt($encrypted, ENCRYPTION_KEY);