TRANSPORT_CRYPTO_MODE 共有三种模式:
off完全关闭传输层加解密。中间件不执行请求解密与响应加密,前端通过/transport/crypto/frontend-config获取到的策略也会同步关闭。optional可选加密模式。命中的接口既接受明文请求,也接受加密请求;如果请求已加密,后端会解密后处理,并对命中的 JSON 响应自动加密。适合灰度接入和上线初期观察。required强制加密模式。命中的接口必须携带合法加密信封,明文请求会被直接拒绝;同时防重放校验会按严格模式执行,Redis 不可用时也会拒绝请求。适合链路稳定后的正式强制启用阶段。
补充说明:
TRANSPORT_CRYPTO_ENABLED=false时,整体效果等同于关闭,不再进入传输层加解密逻辑。TRANSPORT_CRYPTO_ENABLED_PATHS、TRANSPORT_CRYPTO_REQUIRED_PATHS和TRANSPORT_CRYPTO_EXCLUDE_PATHS会在上述模式基础上继续约束命中范围。
开发环境直接使用 .env.dev 中默认提供的可用密钥对即可。
说明:
- 传输层加解密启用后,后端启动时必须读到一对匹配的
TRANSPORT_CRYPTO_PUBLIC_KEY/TRANSPORT_CRYPTO_PRIVATE_KEY。 - 前端会自动读取
/transport/crypto/frontend-config,并跟随后端配置完成请求加密、响应解密。 /transport/crypto/frontend-config和/transport/crypto/public-key为公开接口,已配置匿名限流,前端会直接调用这两个接口完成初始化。TRANSPORT_CRYPTO_FRONTEND_CONFIG_TTL_SECONDS用于控制前端多久重新拉取一次运行策略。TRANSPORT_CRYPTO_PUBLIC_KEY_TTL_SECONDS用于控制前端多久重新拉取一次公钥,两者已经独立。
生产环境使用后端 .env.prod 中的密钥配置;仓库默认提供一套可用示例值,正式部署前请替换为正式密钥。
推荐最小配置如下:
TRANSPORT_CRYPTO_ENABLED=true
TRANSPORT_CRYPTO_MODE='optional'
TRANSPORT_CRYPTO_KID='2026-prod-v1'
TRANSPORT_CRYPTO_PUBLIC_KEY='-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----\n'
TRANSPORT_CRYPTO_PRIVATE_KEY='-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n'
TRANSPORT_CRYPTO_LEGACY_KEY_PAIRS='[]'
TRANSPORT_CRYPTO_FRONTEND_CONFIG_TTL_SECONDS=300
TRANSPORT_CRYPTO_PUBLIC_KEY_TTL_SECONDS=3600
TRANSPORT_CRYPTO_CLOCK_SKEW_SECONDS=120
TRANSPORT_CRYPTO_MAX_GET_URL_LENGTH=4096说明:
TRANSPORT_CRYPTO_PUBLIC_KEY和TRANSPORT_CRYPTO_PRIVATE_KEY必须是一对匹配密钥,缺一不可。TRANSPORT_CRYPTO_KID表示当前启用的密钥版本。TRANSPORT_CRYPTO_FRONTEND_CONFIG_TTL_SECONDS控制/transport/crypto/frontend-config的前端缓存时长,适合在策略经常调整时适当缩短。TRANSPORT_CRYPTO_PUBLIC_KEY_TTL_SECONDS控制/transport/crypto/public-key的前端缓存时长,主要服务于公钥缓存与密钥轮换。TRANSPORT_CRYPTO_CLOCK_SKEW_SECONDS建议控制在60-120秒,默认收紧为120秒。TRANSPORT_CRYPTO_REPLAY_TTL_SECONDS控制防重放随机数在 Redis 中的有效期;如果准备使用required模式,建议保证 Redis 稳定可用。- 初次上线建议先用
TRANSPORT_CRYPTO_MODE='optional',确认链路稳定后再考虑切到required。 TRANSPORT_CRYPTO_MAX_GET_URL_LENGTH用于限制 GET/DELETE 请求加密后的 URL 长度,前端会通过/transport/crypto/frontend-config自动同步该值,超限时直接提示改用 POST 或精简查询条件。- 传输层加密主要面向查询参数、
application/json与application/x-www-form-urlencoded请求;multipart/form-data上传和下载接口默认排除。
当前项目的 Docker 部署使用:
docker-compose.my.yml+Dockerfile.mydocker-compose.pg.yml+Dockerfile.pg
后端容器启动命令分别是:
python app.py --env=dockermypython app.py --env=dockerpg
所以 Docker 环境需要直接在以下文件中配置传输层密钥:
ruoyi-fastapi-backend/.env.dockermyruoyi-fastapi-backend/.env.dockerpg
配置方式与生产环境相同;.env.dockermy / .env.dockerpg 里也已经默认提供一套可用示例值,正式部署前请替换为正式密钥。
使用时只需要:
- 修改对应的
.env.dockermy或.env.dockerpg - 重新构建并启动 Docker 服务
使用 openssl 生成一套 RSA 密钥:
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096 -out transport_private.pem
openssl rsa -pubout -in transport_private.pem -out transport_public.pem如果需要写入 .env,先转成单行带 \n 的格式:
awk 'NF {sub(/\r/, ""); printf "%s\\\\n",$0;}' transport_private.pem
awk 'NF {sub(/\r/, ""); printf "%s\\\\n",$0;}' transport_public.pem- 后端启动时读取当前
TRANSPORT_CRYPTO_*配置,并校验公私钥是否同时存在且彼此匹配。 - 前端通过
/transport/crypto/frontend-config获取当前运行策略,再通过/transport/crypto/public-key获取当前kid、协议版本和公钥。 TRANSPORT_CRYPTO_FRONTEND_CONFIG_TTL_SECONDS和TRANSPORT_CRYPTO_PUBLIC_KEY_TTL_SECONDS分别控制这两类缓存的刷新周期。- 前端用公钥加密请求,后端用私钥解密请求。
- 后端会对命中的 JSON 响应自动加密,前端自动解密;下载、上传等排除场景保持明文。
如果需要更换密钥:
- 生成新密钥对。
- 修改
TRANSPORT_CRYPTO_KID为新版本,例如2026-prod-v2。 - 配置新的
TRANSPORT_CRYPTO_PUBLIC_KEY和TRANSPORT_CRYPTO_PRIVATE_KEY。 - 把旧私钥放入
TRANSPORT_CRYPTO_LEGACY_KEY_PAIRS。
补充说明:
TRANSPORT_CRYPTO_LEGACY_KEY_PAIRS主要用于兼容旧报文解密,最少提供kid和旧私钥即可;publicKey可选,不填时后端会从私钥推导。- 轮换期间建议保留旧私钥直到旧公钥缓存全部过期,至少覆盖
TRANSPORT_CRYPTO_PUBLIC_KEY_TTL_SECONDS对应的缓存窗口。
示例:
TRANSPORT_CRYPTO_KID='2026-prod-v2'
TRANSPORT_CRYPTO_LEGACY_KEY_PAIRS='[{"kid":"2026-prod-v1","privateKey":"-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n"}]'