Home >PHP >PHP reference – functions >openssl_encrypt

openssl_encrypt

openssl_encrypt($data, $cipher_algo, $passphrase, $options = 0, $iv = "", &$tag = null, $aad = "", $tag_length = 16)

Encrypts data with a chosen cipher and key. For new data aes-256-gcm is suitable: it encrypts and also adds an authentication tag, so decryption detects whether anyone has tampered with the data. Returns the encrypted data (in base64 without the OPENSSL_RAW_DATA option), or false on failure.

Parameters

  • $data – the text to encrypt.
  • $cipher_algo – the name of the cipher: aes-256-gcm (recommended), aes-256-cbc, chacha20-poly1305…
  • $passphrase – the key: random bytes of the right length (32 bytes for AES-256), not a password.
  • $options – OPENSSL_RAW_DATA = return binary data instead of base64.
  • $iv – the initialization vector: a new random one for each encryption, openssl_cipher_iv_length() returns its length.
  • &$tag – with GCM the function writes the authentication tag here (needed for decryption); $aad – data that is verified but not encrypted.

Examples

// the key: 32 random bytes, stored outside the database (in .env or the configuration)
$key = random_bytes(32);
$iv = random_bytes(openssl_cipher_iv_length("aes-256-gcm"));
$encrypted = openssl_encrypt("Passport no. 123456789", "aes-256-gcm", $key, OPENSSL_RAW_DATA, $iv, $tag);
echo strlen($iv) . " " . strlen($tag); // 12 16
// store the IV, the tag and the ciphertext in the database (neither the IV nor the tag is secret)
$stored = base64_encode($iv . $tag . $encrypted);
// decryption
$data = base64_decode($stored);
echo openssl_decrypt(substr($data, 28), "aes-256-gcm", $key, OPENSSL_RAW_DATA, substr($data, 0, 12), substr($data, 12, 16)); // Passport no. 123456789

Things to watch out for

  • Never use the same IV with the same key twice with GCM – it reveals the contents of both messages. Always take the IV from random_bytes().
  • Do not use a password directly as the key. A key is derived from a password with hash_pbkdf2() or sodium_crypto_pwhash() with a random salt.
  • The aes-256-cbc mode has no authentication – without your own HMAC an attacker can modify the ciphertext. Do not use the ECB mode (aes-256-ecb) on real data.
  • User passwords are not encrypted but hashed (password_hash()) – encryption is for data that needs to be read back.

Related functions:
openssl_decrypt()
openssl_cipher_iv_length()
random_bytes()
sodium_crypto_secretbox()
hash_pbkdf2()
base64_encode()