在 PHP 中实现 AES 加密, 常见的方法包括使用 mcrypt 或 OpenSSL
使用 mcrypt
扩展
适用于较老的 PHP 版本 (如 PHP 5.x 和部分 7.x)。mcrypt 扩展从 PHP 7.2 开始被废弃, 且需要额外安装。
安装 mcrypt
扩展
CentOS 7 / PHP 7.2
yum install php72-mcrypt
Debian / Ubuntu / PHP 7.0
sudo apt-get install php7-mcrypt
AES-128-CBC 加密类
// AES-128-CBC 加密类
class AES {
private static $key = 'YourKeyxxxxxxxxx'; // 密钥
private static $iv = 'YourIvxxxxxxxxxx'; // 初始化向量
// 加密方法
public static function encrypt($data) {
$encrypted = mcrypt_encrypt(
MCRYPT_RIJNDAEL_128, // 使用 AES-128
self::$key, // 密钥
self::pkcs7_pad($data), // 填充数据
MCRYPT_MODE_CBC, // CBC 加密模式
self::$iv // IV 初始化向量
);
return base64_encode($encrypted);
}
// 解密方法
public static function decrypt($data) {
$decrypted = mcrypt_decrypt(
MCRYPT_RIJNDAEL_128, // 使用 AES-128
self::$key, // 密钥
base64_decode($data), // 解码后的数据
MCRYPT_MODE_CBC, // CBC 解密模式
self::$iv // IV 初始化向量
);
return self::pkcs7_unpad($decrypted); // 去除填充
}
// PKCS7 填充方法
private static function pkcs7_pad($text) {
$blocksize = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$pad = $blocksize - (strlen($text) % $blocksize);
return $text . str_repeat(chr($pad), $pad); // 填充至整块
}
// 去除 PKCS7 填充
private static function pkcs7_unpad($text) {
$len = strlen($text);
$pad = ord($text[$len - 1]); // 获取填充字节值
return substr($text, 0, $len - $pad); // 去除填充
}
}
使用实例
$data = "test";
// 加密
$encrypted = AES::encrypt($data);
echo $encrypted . "\n";
// $privateKey = "7854156156611111";
// $iv = "0000000000000000";
// 解密
$encryptedData = "L7AswKt5/t1gND4ct22Odw==";
$decrypted = AES::decrypt($encryptedData);
echo $decrypted . "\n";
使用 OpenSSL 实现 AES 加密
对于现代 PHP 版本, mcrypt
已经被废弃, 建议使用 openssl_encrypt
和 openssl_decrypt
。以下是实现 AES 加密和解密的代码, 采用 PKCS7 填充
class AES {
/**
* @param string $string 需要加密的字符串
* @param string $key 密钥
* @return string
*/
public static function encrypt($string, $key) {
// 使用 SHA1PRNG 算法生成加密用的 16 字节密钥 (Java 兼容)
$key = substr(openssl_digest(openssl_digest($key, 'sha1', true), 'sha1', true), 0, 16);
// 生成随机的 16 字节 IV
$iv = openssl_random_pseudo_bytes(16);
// 使用 AES-128-CBC 加密
$data = openssl_encrypt($string, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv);
// 将 IV 和加密数据合并, 并转为 HEX 格式字符串
$data = strtoupper(bin2hex($iv . $data));
return $data;
}
/**
* @param string $string 需要解密的字符串
* @param string $key 密钥
* @return string
*/
public static function decrypt($string, $key) {
// 使用 SHA1PRNG 算法生成解密用的 16 字节密钥 (Java 兼容)
$key = substr(openssl_digest(openssl_digest($key, 'sha1', true), 'sha1', true), 0, 16);
// 将 HEX 格式字符串转换为二进制数据
$data = hex2bin($string);
// 从数据中提取 IV (前 16 字节) 和密文
$iv = substr($data, 0, 16);
$cipherText = substr($data, 16);
// 使用 AES-128-CBC 解密
$decrypted = openssl_decrypt($cipherText, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv);
return $decrypted;
}
}
// 测试
$encrypt = AES::encrypt('test', 'blog.acesheep.com');
$decrypt = AES::decrypt($encrypt, 'blog.acesheep.com');
echo "加密后: " . $encrypt . "\n";
echo "解密: " . $decrypt . "\n";
初始化向量 (IV)
- CBC 模式要求一个初始化向量 (IV), 长度必须与块大小一致 (AES 的块大小为 16 字节)
- 加密时, 使用
openssl_random_pseudo_bytes(16)
生成随机 IV - IV 必须与密文一起存储, 因为解密时需要它
原文
AES/CBC/128/PKCS5Padding加密解密算法 (iOS、Android、JavaScript、PHP)
PHP AES Encryption/Decryption Class with PKCS5 padding
PHP AES加解密(AES-128-ECB|sha1|bin2hex)
md5 Hash Generator
在线AES加密解密、AES在线加密解密、AES encryption and decryption