PHP中使用openssl_decrypt与AES解密邮箱地址失败求助
问题排查与解决:AES加密邮箱URL传递后解密为空
问题根源
从var_dump($_GET)结果可见,eadd参数里的+被替换成了空格:WoN/K2t4xjKb057c EIhg==,但原始加密后的字符串是WoN/K2t4xjKb057c++EIhg==。这是因为URL中+会被浏览器自动解析为空格,导致解密时的字符串与加密时不一致,最终解密失败返回空。
表ID能成功解密,是因为其加密后的base64字符串不含+这类会被URL篡改的特殊字符,传递过程未被修改。
解决方案
加密完成后必须对结果做urlencode处理,确保特殊字符被正确编码,避免URL传递时被篡改。
修改后的加密代码
<?php $email_id = '123456'; $addto = 'test@gmail.com'; // 执行加密 $email_id = openssl_encrypt($email_id, "AES-256-CBC", "25c6c7ff35b9979b151f2136cd13b0ff"); $encto = openssl_encrypt($addto, "AES-256-CBC", "25c6c7ff35b9979b151f2136cd13b0ff"); // 对加密结果进行URL编码,避免特殊字符被篡改 $email_id_encoded = urlencode($email_id); $encto_encoded = urlencode($encto); ?>
生成的URL示例
此时退订URL中的eadd参数会变为WoN%2FK2t4xjKb057c%2B%2BEIhg%3D%3D,+被编码为%2B,传递到后端后PHP的$_GET会自动解码为原始加密字符串。
解密代码无需额外修改
后端解密代码保持原样即可,$_GET会自动处理URL编码的解码:
<?php $eid = $_GET['id']; $eaddr = $_GET['eadd']; $eid = openssl_decrypt($eid, "AES-256-CBC", "25c6c7ff35b9979b151f2136cd13b0ff"); $eaddr = openssl_decrypt($eaddr, "AES-256-CBC", "25c6c7ff35b9979b151f2136cd13b0ff"); ?> <p>Your Email Address is <address><?php echo $eaddr; ?></address></p> <p>Your Id is: <?php echo $eid; ?></p>
额外注意事项
- AES-256-CBC模式规范上需要显式指定初始化向量(IV),当前代码未指定时PHP会自动生成随机IV并附加在加密结果中,虽能正常解密,但为了兼容性和安全性,建议显式生成IV并一同传递(同样需URL编码)。
- 当前使用的密钥
25c6c7ff35b9979b151f2136cd13b0ff为32位,符合AES-256的密钥长度要求,这部分无问题。
内容的提问来源于stack exchange,提问作者Rezbin
相关产品推荐
相关产品推荐

