CryptoJS aes加密的数据包含Salted__ 如何使用php实现
在 PHP 中实现与 OpenSSL 兼容的 AES 加密(含 Salted__ 头),需手动处理盐值生成和密钥派生。以下是完整实现代码及分步说明:
一、加密实现代码
<?php
/**
* AES 加密(兼容 OpenSSL 的 "Salted__" 格式)
* @param string $data 明文数据
* @param string $password 加密密码
* @param string $method 加密算法,如 'AES-256-CBC'
* @return string Base64 编码的加密数据(含 Salted__ 头)
*/
function opensslEncryptWithSalt($data, $password, $method = 'AES-256-CBC') {
// 生成 8 字节随机盐
$salt = openssl_random_pseudo_bytes(8);
// 通过盐和密码派生密钥与 IV
$keyIv = deriveKeyAndIV($password, $salt, $method);
$key = $keyIv['key'];
$iv = $keyIv['iv'];
// 加密数据
$encrypted = openssl_encrypt($data, $method, $key, OPENSSL_RAW_DATA, $iv);
// 拼接 Salted__ 头 + 盐 + 密文
$result = "Salted__" . $salt . $encrypted;
// Base64 编码便于传输
return base64_encode($result);
}
/**
* 派生密钥和 IV(模拟 OpenSSL 的 EVP_BytesToKey)
*/
function deriveKeyAndIV($password, $salt, $method) {
$digest = 'md5'; // OpenSSL 默认使用 MD5
$keySize = 32; // AES-256 需要 32 字节密钥
$ivSize = 16; // CBC 模式需要 16 字节 IV
$derived = '';
$data = '';
$length = 0;
while ($length < $keySize + $ivSize) {
$data = $data . $password . $salt;
$md5 = hash($digest, $data, true);
$data = $md5;
$derived .= $md5;
$length += strlen($md5);
}
return [
'key' => substr($derived, 0, $keySize),
'iv' => substr($derived, $keySize, $ivSize)
];
}
二、解密实现代码
<?php
/**
* AES 解密(兼容 OpenSSL 的 "Salted__" 格式)
* @param string $encryptedData Base64 编码的加密数据
* @param string $password 解密密码
* @param string $method 加密算法,如 'AES-256-CBC'
* @return string 解密后的明文
*/
function opensslDecryptWithSalt($encryptedData, $password, $method = 'AES-256-CBC') {
// 解码 Base64
$data = base64_decode($encryptedData);
// 提取盐(前 8 字节,跳过 "Salted__" 头)
$salt = substr($data, 8, 8);
// 提取密文(去除头部的 16 字节:Salted__ + 盐)
$encrypted = substr($data, 16);
// 派生密钥和 IV
$keyIv = deriveKeyAndIV($password, $salt, $method);
$key = $keyIv['key'];
$iv = $keyIv['iv'];
// 解密数据
return openssl_decrypt($encrypted, $method, $key, OPENSSL_RAW_DATA, $iv);
}
三、使用示例
<?php
// 加密示例
$plaintext = "Hello, World!";
$password = "mySecretPassword";
$encrypted = opensslEncryptWithSalt($plaintext, $password);
echo "加密结果: " . $encrypted . "\n";
// 解密示例
$decrypted = opensslDecryptWithSalt($encrypted, $password);
echo "解密结果: " . $decrypted . "\n";
四、核心逻辑说明
1. 盐值生成