CFML通过URL传递AES密钥报密钥长度无效错误如何解决
问题定位
首先澄清:报错指向deserializeJSON()执行行不代表JSON反序列化逻辑有问题,ColdFusion执行嵌套语句时会优先计算括号内的decrypt()逻辑,实际报错来自解密环节。
核心根因
你对密钥做了重复URL解码:
ColdFusion的url作用域会自动对所有传入的URL参数完成一次URL解码,你在home页额外调用DecodeFromURL(url.str)等于对密钥做了两次解码,直接破坏了base64编码的密钥结构。
AES128对应的原始密钥是16字节,经过base64编码后长度为24字符(末尾带两个=填充符),两次解码会导致填充符丢失、特殊字符转义错误,最终base64解码出来的密钥字节数不符合128位要求,就会抛出长度异常。
解决方案
1. 直接修复(立刻生效)
删除home页多余的DecodeFromURL()调用,直接从url作用域取密钥即可:
if ( structKeyExists(url, "str") ) { key = url.str; // url作用域已自动完成URL解码,无需二次处理 strData = deserializeJSON(decrypt(url.dt, key, "AES", "HEX")); } else { writeOutput("<p>Error! Please contact your administrator.</p>"); abort; }
2. 可选优化(避免兼容问题)
- 将入口页的301永久重定向改为302临时重定向,避免浏览器缓存旧的跳转链接导致后续解密失败:
location("home.cfm?str=#encodeForURL(key)#&dt=#data#", "false", "302"); - 若担心不同服务端的URL解码规则差异,可以对密钥做URL安全的base64转码:入口页将密钥的
+替换为-、/替换为_、删除末尾=,home页拿到后反向转换补全填充符,彻底规避编码转义问题。
验证步骤
如果修改后仍有问题,可按以下步骤排查:
- 在入口页输出生成的
key的内容和长度,正常AES128的base64编码密钥长度为24字符 - 在home页输出
url.str的内容和长度,和入口页的原始密钥对比,确认二者完全一致 - 单独输出
decrypt(url.dt, key, "AES", "HEX")的结果,确认解密后得到的是合法JSON字符串,排除加密算法参数不匹配的问题
内容的提问来源于stack exchange,提问作者espresso_coffee
相关产品推荐
相关产品推荐

