Cryptography in PHP: Encryption and Hashing — Complete Guide
In modern web development, data security is one of the key priorities. PHP provides powerful built-in tools for cryptographic protection: from simple password hashing to complex asymmetric encryption. In this article, we will cover the main approaches, libraries, and best practices for working with cryptography in PHP.
1. Data Hashing
Hashing is an irreversible transformation of data into a fixed-length string. It is used for storing passwords, verifying file integrity, and creating digital signatures.
1.1. Password Hashing (password_hash)
Starting with PHP 5.5, it is recommended to use the password_hash() function for password hashing. It automatically selects a secure algorithm (bcrypt by default) and generates a salt.
<?php// Password hashing$password = 'MySecurePassword123!';$hash = password_hash($password, PASSWORD_DEFAULT);
echo "Hash: " . $hash . "";
// Password verificationif (password_verify($password, $hash)) { echo "Password is correct!";} else { echo "Invalid password!";}?>1.2. Hashing with hash()
For other purposes (e.g., file checksums), use the hash() function with SHA-256, SHA-512, or BLAKE2 algorithms.
<?php$data = "Secret data";$sha256_hash = hash('sha256', $data);$blake2b_hash = hash('blake2b', $data);
echo "SHA-256: " . $sha256_hash . "";echo "BLAKE2b: " . $blake2b_hash . "";?>2. Symmetric Encryption
Symmetric encryption uses the same key for encrypting and decrypting data. In PHP, the OpenSSL extension is used for this purpose.
2.1. Encryption with AES-256-GCM (Authenticated Encryption)
The recommended mode is AES-256-GCM, which provides confidentiality and integrity verification.
<?php$plaintext = "Confidential message";$key = random_bytes(32); // 256-bit key$iv = random_bytes(12); // 96-bit initialization vector
// Encryption$ciphertext = openssl_encrypt( $plaintext, 'aes-256-gcm', $key, OPENSSL_RAW_DATA, $iv, $tag);
echo "Encrypted data (base64): " . base64_encode($ciphertext) . "";echo "Authentication tag: " . bin2hex($tag) . "";
// Decryption$decrypted = openssl_decrypt( $ciphertext, 'aes-256-gcm', $key, OPENSSL_RAW_DATA, $iv, $tag);
echo "Decrypted: " . $decrypted . "";?>2.2. Encryption with AES-256-CBC (for Compatibility)
If compatibility with legacy systems is required, use AES-256-CBC with HMAC for integrity verification.
<?phpfunction encryptAesCbc($plaintext, $key) { $iv = random_bytes(16); $ciphertext = openssl_encrypt($plaintext, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv); $hmac = hash_hmac('sha256', $iv . $ciphertext, $key, true); return base64_encode($hmac . $iv . $ciphertext);}
function decryptAesCbc($data, $key) { $data = base64_decode($data); $hmac = substr($data, 0, 32); $iv = substr($data, 32, 16); $ciphertext = substr($data, 48); $expectedHmac = hash_hmac('sha256', $iv . $ciphertext, $key, true); if (!hash_equals($hmac, $expectedHmac)) { throw new Exception("Data integrity violation!"); } return openssl_decrypt($ciphertext, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);}
$key = random_bytes(32);$encrypted = encryptAesCbc("Secret data", $key);echo "Encrypted: " . $encrypted . "";echo "Decrypted: " . decryptAesCbc($encrypted, $key) . "";?>3. Asymmetric Encryption
Asymmetric encryption uses a pair of keys: a public key (for encryption)