up. 双向数据加密

This commit is contained in:
u2nyakim 2025-08-29 15:49:20 +08:00
parent 7a072e4bec
commit bae500bd2c

View File

@ -160,45 +160,48 @@ class ContextMiddleware extends middleware
* @throws ValidateException 解密失败时抛出异常 * @throws ValidateException 解密失败时抛出异常
*/ */
private function decryptCryptoJSData(string $encryptedData): array private function decryptCryptoJSData(string $encryptedData): array
{// 1. Base64 解码加密数据 {
$encrypted = base64_decode($encryptedData); // Base64解码
$data = base64_decode($encryptedData);
// 2. 提取初始化向量 (IV) - 前16字节 // 检查Salted__头
if (strlen($encrypted) < 16) { if (!str_starts_with($data, "Salted__")) {
throw new ValidateException('加密数据太短无法提取IV'); throw new ValidateException('Invalid format: missing "Salted__" header');
} }
$iv = substr($encrypted, 0, 16); // 提取Salt (8字节)
$ciphertext = substr($encrypted, 16); $salt = substr($data, 8, 8);
$ct = substr($data, 16);
// 3. 准备解密密钥 // 通过EVP_BytesToKey派生密钥和IV
// CryptoJS 使用密钥派生函数,这里使用简单的 SHA256 哈希 $keyIv = $this->evpBytesToKey($salt);
$key = substr(hash('sha256', self::DATA_SECRET_KEY, true), 0, 32); $key = $keyIv['key'];
$iv = $keyIv['iv'];
// 4. 使用 AES-256-CBC 解密 // AES-256-CBC解密
$decrypted = openssl_decrypt( $decrypted = openssl_decrypt(
$ciphertext, $ct,
'AES-256-CBC', 'aes-256-cbc',
$key, $key,
OPENSSL_RAW_DATA, OPENSSL_RAW_DATA,
$iv $iv
); );
return json_decode($decrypted, true);
}
if ($decrypted === false) { private function evpBytesToKey($salt): array
throw new ValidateException('解密失败: ' . openssl_error_string()); {
$password = self::DATA_SECRET_KEY;
$bytes = '';
$last = '';
// 生成48字节32字节key + 16字节IV
while(strlen($bytes) < 48) {
$last = md5($last . $password . $salt, true);
$bytes .= $last;
} }
return [
// 5. 移除 PKCS#7 填充 'key' => substr($bytes, 0, 32),
$padding = ord($decrypted[strlen($decrypted) - 1]); 'iv' => substr($bytes, 32, 16)
$decrypted = substr($decrypted, 0, -$padding); ];
// 6. 解析为 JSON
$data = json_decode($decrypted, true);
if (json_last_error() !== JSON_ERROR_NONE) {
throw new ValidateException('JSON 解析失败: ' . json_last_error_msg());
}
return $data;
} }
} }