OpenResty lua-resty-string AES-GCM解密失败问题求助
排查lua-resty-string解密AES-GCM失败的常见问题
先明确lua-resty-string中AES-GCM的解密规则:它要求密文和认证标签(tag)拼接为一个字节流传入解密接口,同时必须保证key、iv、密文/tag的编码、长度完全符合标准。以下是最容易踩坑的几个点:
1. 密文与Tag的拼接顺序错误
Go/Python的AES-GCM实现通常支持单独传入密文和tag,但lua-resty-string的aes:decrypt方法要求将tag直接追加在密文末尾作为整体输入。如果你是分开传递两者、或者拼接顺序搞反,必然解密失败。
正确处理示例:
local resty_aes = require "resty.aes" local resty_str = require "resty.string" -- 假设enc是base64编码的「密文+tag」组合体,先解码为原始字节 local encrypted_data = resty_str.decode_base64(enc) -- key需对应16/24/32字节(对应AES-128/192/256),iv推荐用12字节 local aes, err = resty_aes:new(key, nil, resty_aes.cipher(256, "gcm"), {iv = iv}) if not aes then ngx.log(ngx.ERR, "创建AES实例失败: ", err) return end local decrypted, err = aes:decrypt(encrypted_data) if not decrypted then ngx.log(ngx.ERR, "解密失败: ", err) return end
2. Key/IV的编码或长度不符
- AES-GCM的key必须是16(128位)、24(192位)或32(256位)字节长度。如果你的key是hex/base64编码的字符串,必须先解码为原始字节,不能直接传入字符串。
- IV(初始向量)推荐用12字节长度,lua-resty-string严格遵循这个标准,长度不符会直接报错。
比如key是hex编码的32字节字符串,正确处理方式:
-- 将hex字符串转原始字节 local key_bytes = resty_str.from_hex(key) -- iv同理,若为编码格式需先解码 local iv_bytes = resty_str.from_hex(iv) local aes = resty_aes:new(key_bytes, nil, resty_aes.cipher(256, "gcm"), {iv = iv_bytes})
3. 遗漏附加认证数据(AAD)处理
如果你的Go/Python解密时用到了附加认证数据(AAD),lua-resty-string解密时必须同步添加对应AAD,否则会触发认证失败。
添加AAD的示例:
local ok, err = aes:set_aad(aad_raw_bytes) -- aad_raw_bytes是原始字节数据 if not ok then ngx.log(ngx.ERR, "设置AAD失败: ", err) return end local decrypted = aes:decrypt(encrypted_data)
4. 编码转换错误
如果你的enc是base64或hex编码,必须在lua中显式解码为原始字节。部分语言会自动处理编码转换,但lua-resty-string需要你手动调用resty_str.decode_base64或resty_str.from_hex完成转换。
如果能提供你的Go/Python代码片段,可以更精准定位问题,但先按以上几点排查,大概率是其中某一步不符合lua-resty-string的要求。
内容的提问来源于stack exchange,提问作者ccwang
相关产品推荐
相关产品推荐

