OpenResty通过Lua脚本在Nginx生命周期关键阶段(access/body/header_filter_by_lua*)实现接口参数自动化加解密,需按路径、请求头、身份标识等规则精准识别目标请求,兼顾安全性、兼容性与性能。

OpenResty 通过 Lua 脚本实现接口参数的自动化加解密,核心在于把加密/解密逻辑嵌入到 Nginx 请求生命周期的关键阶段(如 access_by_lua*、body_filter_by_lua*、header_filter_by_lua*),并结合业务规则判断是否触发处理。不是所有请求都需加解密,重点是识别目标请求、安全拦截原始数据、调用可靠加解密模块、保持协议兼容性。
识别需要加解密的请求
不能对全部流量盲目加解密,需按明确规则筛选:
- 匹配特定路径前缀(如
/api/v2/secure)或 HTTP 方法(如仅 POST/PUT 的 JSON 接口) - 检查请求头(如
X-Encrypt: true或Content-Type: application/encrypted+json) - 校验客户端身份标识(如合法 AppID + Token 组合,从 Redis 或本地缓存中查白名单)
- 排除已压缩(
Content-Encoding: gzip)、重定向(304)、大文件(>5MB)等不适用场景
在请求阶段自动解密参数
对客户端发来的加密参数(如整个 request body 是 AES 加密的 JSON),在进入后端服务前完成透明解密:
- 使用
access_by_lua_block或rewrite_by_lua_block拦截请求,读取原始 body(注意开启client_body_buffer_size和client_max_body_size) - 调用 Lua 解密函数(如
aes_decrypt(data, key, iv)),支持 CBC/PKCS#7 填充;密钥建议从安全配置中心拉取,避免硬编码 - 将解密后的明文 JSON 替换原
ngx.var.request_body,或注入为新变量(如ngx.ctx.decrypted_json)供后续 location 使用 - 若使用 multipart 表单,需先解析 boundary,再对指定字段(如
data)单独解密
在响应阶段自动加密返回内容
后端返回明文 JSON 后,由 OpenResty 在发给客户端前加密:
- 用
body_filter_by_lua_block累积响应体(因响应可能分块),直到收到最后一块或检测到完整 JSON 结构 - 对完整响应体执行加密(如 AES-GCM,附带认证标签),设置新
Content-Type: application/encrypted+json - 用
header_filter_by_lua_block删除或覆盖原始Content-Length(因加密后长度变化),添加自定义头如X-Encrypted: aes-gcm-256 - 若需兼容老客户端,可依据请求头
Accept-Encryption决定是否启用加密
关键注意事项
实际落地时容易踩坑,需特别关注:
- 加解密必须幂等且无状态,避免因 Nginx 多 worker 或请求重试导致重复加解密
- IV 必须每次随机生成并随密文传输(如 Base64 编码后拼接在密文前),不可复用
- 错误处理要明确:解密失败统一返回
400 Bad Request并记录日志,不透出密钥或算法细节 - 性能敏感接口建议启用 LuaJIT 缓存(
lua_code_cache on),加密模块优先用 C 封装(如lddf_64.so)而非纯 Lua 实现


















