php返回json前通常无需加密,应优先使用https;仅第三方回调和内部微服务通信等特定场景需加密,且须严格遵循iv随机生成、密钥长度匹配、base64编码等规范。

PHP 返回 JSON 前要不要加密?先看场景
大多数情况下,json_encode() 后直接输出的 JSON **不需要、也不该由 PHP 层加密**。浏览器或 App 拿到的是明文,但传输层该走 HTTPS 就走 HTTPS;如果真要防中间人或防调试抓包,靠 PHP 加密 JSON 是伪安全——密钥藏在哪?JS 怎么解?反而暴露逻辑、增加维护成本。
真正需要加密的典型场景只有两个:
- 第三方系统回调(比如支付通知),要求你用 AES 对响应体加密后再返回
- 内部微服务间通信,且明确约定使用对称密钥做 payload 加密(非 HTTP Header 或 Token)
用 openssl_encrypt() 加密 JSON 字符串的正确姿势
核心是:先 json_encode(),再加密,最后 base64 编码(因为加密结果含二进制字节,不能直接塞进 HTTP 响应体)。
$data = ['status' => 'success', 'uid' => 123];
$json = json_encode($data, JSON_UNESCAPED_UNICODE);
$method = 'AES-256-CBC';
$key = '32-byte-key-must-be-exactly-this-length'; // 必须严格32字节
$ivlen = openssl_cipher_iv_length($method);
$iv = openssl_random_pseudo_bytes($ivlen); // 每次生成新 IV
$encrypted = openssl_encrypt($json, $method, $key, 0, $iv);
$result = [
'data' => base64_encode($encrypted),
'iv' => base64_encode($iv)
];
header('Content-Type: application/json');
echo json_encode($result, JSON_UNESCAPED_UNICODE);
注意点:
-
openssl_encrypt()的$options参数必须为0(不是OPENSSL_RAW_DATA),否则和默认行为不一致 -
$key长度必须匹配算法:AES-256 要 32 字节,AES-128 要 16 字节,用strlen($key)校验过再上线 -
$iv必须随密文一起传出去,且每次请求都该是新的,不能硬编码
常见报错:openssl_encrypt(): Using an empty Initialization Vector
这通常不是 IV 真为空,而是你传了 null 或空字符串给 $iv 参数,而函数没做容错就直接崩了。
排查步骤:
- 检查
$iv是否真的被赋值,var_dump($iv)看长度是不是 16(AES-128)或 16(AES-256-CBC 同样要 16 字节 IV) - 不要用
md5()或sha1()截取当 IV,它们输出是 hex 字符串,长度翻倍且含非法字符 - 如果从请求里读 IV,确保它经过
base64_decode()再传入openssl_decrypt()
前端解密失败?大概率是 padding 或编码不一致
PHP 默认用 PKCS#7 填充,JS 的 CryptoJS 或 Web Crypto API 默认可能不同。例如:
- CryptoJS 解密时必须显式指定
{ padding: CryptoJS.pad.Pkcs7 }
- Web Crypto 的
decrypt() 要用 AesCbcParams,且 iv 必须是 Uint8Array,不是 base64 字符串
- PHP 的
json_encode() 若含中文,默认转成 \uXXXX,而有些 JS 解密后直接拼 JSON 字符串,会导致解析失败;建议加 JSON_UNESCAPED_UNICODE
{ padding: CryptoJS.pad.Pkcs7 } decrypt() 要用 AesCbcParams,且 iv 必须是 Uint8Array,不是 base64 字符串 json_encode() 若含中文,默认转成 \uXXXX,而有些 JS 解密后直接拼 JSON 字符串,会导致解析失败;建议加 JSON_UNESCAPED_UNICODE 加密本身不难,难的是两端对齐:IV 生成方式、密钥来源、padding 规则、base64 编码层级、字符集处理。漏掉任何一环,都是“能加密不能解”或者“能解不能 JSON.parse”。
立即学习“PHP免费学习笔记(深入)”;











