PHP 8.1实现URL中JSON数据的合规加密与解密方案
PHP 8.1 实现指定密钥的URL安全加解密方案
核心思路
采用AES-256-GCM加密算法(带数据完整性验证的安全加密方案,可防止数据篡改),配合URL安全的Base64编码(将加密后二进制数据转换为符合要求的字符集),通过指定密钥完成跨域名的加解密操作。
加密实现步骤
- 直接使用JSON字符串作为加密源(PHP字符串本身就是字节流,无需额外转换)
- 生成12字节随机初始化向量(IV):AES-GCM标准推荐长度,确保每次加密结果唯一
- 将用户指定密钥转换为32字节的AES-256标准密钥(通过SHA256哈希生成,适配任意长度的输入密钥)
- 执行加密并获取认证标签(用于解密时验证数据是否被篡改)
- 拼接IV、加密数据、认证标签为二进制数据
- 转换为URL安全格式:标准Base64编码后,将
+替换为-,去掉末尾的=(=不在允许的字符集中)
解密实现步骤
- 还原URL安全编码:把加密字符串中的
-换回+,补全=使字符串长度为4的倍数(满足Base64解码要求) - Base64解码得到二进制数据
- 拆分出IV(前12字节)、认证标签(后16字节)、加密数据(中间部分)
- 用相同密钥生成32字节AES密钥,执行解密并验证认证标签
- 将解密后的字符串解析为JSON格式
完整代码示例
<?php // 加密UTM JSON数据 function encryptUtmData(string $jsonData, string $key): string { // 生成32字节AES-256标准密钥 $aesKey = hash('sha256', $key, true); // 生成12字节随机IV $iv = random_bytes(12); // AES-256-GCM加密,同时获取认证标签 $encrypted = openssl_encrypt( $jsonData, 'aes-256-gcm', $aesKey, OPENSSL_RAW_DATA, $iv, $tag ); // 拼接IV、加密数据、认证标签 $combinedData = $iv . $encrypted . $tag; // 转为URL安全的Base64格式 $base64Str = base64_encode($combinedData); return str_replace('+', '-', rtrim($base64Str, '=')); } // 解密加密后的字符串 function decryptUtmData(string $encryptedStr, string $key): ?string { // 还原标准Base64格式 $base64Str = str_replace('-', '+', $encryptedStr); $base64Str .= str_repeat('=', (4 - strlen($base64Str) % 4) % 4); // Base64解码 $combinedData = base64_decode($base64Str); if ($combinedData === false) { return null; } // 拆分IV、加密数据、认证标签 $iv = substr($combinedData, 0, 12); $tag = substr($combinedData, -16); $encryptedData = substr($combinedData, 12, -16); // 生成32字节AES-256标准密钥 $aesKey = hash('sha256', $key, true); // 解密并验证数据完整性 $decryptedJson = openssl_decrypt( $encryptedData, 'aes-256-gcm', $aesKey, OPENSSL_RAW_DATA, $iv, $tag ); return $decryptedJson; } // 使用示例 $sharedSecretKey = 'your-private-shared-key'; // 加解密双方共享的密钥 $originalUtmJson = '{"utm_source":"google","utm_medium":"cpc","utm_campaign":"summer_sale","utm_term":"running_shoes","utm_content":"banner_ad"}'; // 加密生成可传递的URL字符串 $encryptedStr = encryptUtmData($originalUtmJson, $sharedSecretKey); $targetUrl = "example.com/{$encryptedStr}"; echo "加密后可发送的URL:{$targetUrl}\n"; // 解密验证 $decryptedJson = decryptUtmData($encryptedStr, $sharedSecretKey); if ($decryptedJson) { $utmData = json_decode($decryptedJson, true); echo "解密后的UTM数据:\n"; print_r($utmData); } else { echo "解密失败,数据可能被篡改或密钥错误\n"; } ?>
关键注意事项
- 密钥保密:密钥必须在加解密双方之间安全传递,且全程保密
- IV唯一性:每次加密都要生成新的随机IV,禁止重复使用同一IV和密钥的组合,否则会严重降低加密安全性
- 数据校验:AES-GCM的认证标签会自动验证数据完整性,解密失败时返回
false,可直接判断数据是否被篡改 - 环境要求:确保PHP已启用
openssl扩展(PHP8.1默认已启用,若未开启需在php.ini中配置) - 字符合规:加密后的字符串仅包含[A-Z,a-z,0-9,-,/],完全符合需求中的字符限制
内容的提问来源于stack exchange,提问作者Mixtuur
相关产品推荐
相关产品推荐

