PHP中的密码学:加密与哈希——完整指南
在现代Web开发中,数据安全是首要任务之一。PHP提供了强大的内置工具用于密码学保护:从简单的密码哈希到复杂的非对称加密。本文将介绍PHP中密码学的主要方法、库和最佳实践。
1. 数据哈希
哈希是将数据不可逆地转换为固定长度字符串的过程。它用于存储密码、验证文件完整性和创建数字签名。
1.1. 密码哈希 (password_hash)
从PHP 5.5开始,推荐使用password_hash()函数进行密码哈希。它会自动选择可靠的算法(默认使用bcrypt)并生成盐值。
<?php// 密码哈希$password = 'MySecurePassword123!';$hash = password_hash($password, PASSWORD_DEFAULT);
echo "哈希值: " . $hash . "";
// 密码验证if (password_verify($password, $hash)) { echo "密码正确!";} else { echo "密码错误!";}?>1.2. 使用hash()进行哈希
对于其他用途(例如文件校验和),请使用hash()函数配合SHA-256、SHA-512或BLAKE2算法。
<?php$data = "秘密数据";$sha256_hash = hash('sha256', $data);$blake2b_hash = hash('blake2b', $data);
echo "SHA-256: " . $sha256_hash . "";echo "BLAKE2b: " . $blake2b_hash . "";?>2. 对称加密
对称加密使用相同的密钥进行数据的加密和解密。在PHP中,这通过OpenSSL扩展实现。
2.1. 使用AES-256-GCM加密(认证加密)
推荐使用AES-256-GCM模式,它提供机密性和完整性验证。
<?php$plaintext = "机密消息";$key = random_bytes(32); // 256位密钥$iv = random_bytes(12); // 96位初始化向量
// 加密$ciphertext = openssl_encrypt( $plaintext, 'aes-256-gcm', $key, OPENSSL_RAW_DATA, $iv, $tag);
echo "加密数据 (base64): " . base64_encode($ciphertext) . "";echo "认证标签: " . bin2hex($tag) . "";
// 解密$decrypted = openssl_decrypt( $ciphertext, 'aes-256-gcm', $key, OPENSSL_RAW_DATA, $iv, $tag);
echo "解密结果: " . $decrypted . "";?>2.2. 使用AES-256-CBC加密(用于兼容性)
如果需要与旧系统兼容,请使用AES-256-CBC配合HMAC进行完整性验证。
<?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("数据完整性被破坏!"); } return openssl_decrypt($ciphertext, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);}
$key = random_bytes(32);$encrypted = encryptAesCbc("秘密数据", $key);echo "加密结果: " . $encrypted . "";echo "解密结果: " . decryptAesCbc($encrypted, $key) . "";?>3. 非对称加密
非对称加密使用一对密钥:公钥(用于加密)