全链路实战)
抓包还能看到密码Vue3 Spring Boot 3 接口 AES/RSA 加解密ApiEncrypt全链路实战一句话HTTPS 管「路上」ApiEncrypt管「包里」——敏感接口的 Body 在到达 Controller 之前就该是密文前端 axios 一眼看不见明文 JSON。开源仓库GitCode · RuoyiOfficeAtomGit · RuoyiOffice为什么「已经上了 HTTPS」还不够场景HTTPS 帮得上吗密文 Body 帮得上吗公网链路被窃听✅✅双重员工本机 Fiddler / Charles 装根证书❌ 明文尽收眼底✅ Body 仍是乱码前端误把密码打进 console / 埋点部分减少传输侧泄露面数据库被拖库❌❌要靠落库字段加密接口被重放❌❌要靠签名 nonce 时效很多团队把「传输安全」和「存储安全」「防重放」揉成一锅粥。RuoyiOffice 里其实是三件独立兵器能力解决什么关键词API 传输加解密抓包看不到业务 JSONApiEncrypt/ Filter /X-Api-Encrypt字段落库加密DBA/备份文件看不到手机号TypeHandler / 列级密文API 签名防篡改、防重放appId timestamp sign本文只打透第一件请求解密 响应加密的前后端全链路。登录页本身是敏感入口的典型——密码绝不能以「可复制的明文 JSON」躺在抓包工具里。全链路长什么样Vue3 RequestClient │ headers.isEncrypt true │ data AES/RSA.encrypt(JSON) │ Header: X-Api-Encrypt: true ▼ HTTP POST /admin-api/... Body Base64/密文串 ▼ ApiEncryptFilter早于 Controller、早于多数业务 Filter 可读点 │ 有加密头 → DecryptRequestWrapper 还原明文 Body │ 方法标了 ApiEncrypt(requesttrue) 却无加密头 → 直接拒 ▼ Controller / Service 以为自己在收普通 VO ▼ 若 responsetrue → EncryptResponseWrapper 写出密文 响应头 ▼ 前端响应拦截器见加密头 → decrypt → 再走统一 Result 解析设计上有个关键取舍不用RequestBodyAdvice/ResponseBodyAdvice而用Servlet Filter。原因很务实——访问日志、异常日志、签名校验往往要在「业务反序列化之前」看到原始字节流Filter 更靠前、更可控。后端一个注解两种开关Target({ElementType.TYPE,ElementType.METHOD})Retention(RetentionPolicy.RUNTIME)publicinterfaceApiEncrypt{/** 是否解密请求体默认 true */booleanrequest()defaulttrue;/** 是否加密响应体默认 true */booleanresponse()defaulttrue;}用法示例示意PostMapping(/update-password)ApiEncrypt// 请求解密 响应加密publicCommonResultBooleanupdatePassword(RequestBodyValidPwdReqreq){// req 里已是明文业务无感知加解密returnsuccess(userService.updatePassword(req));}GetMapping(/profile)ApiEncrypt(requestfalse,responsetrue)// 只加密出参publicCommonResultProfileVOgetProfile(){...}Filter 核心分支概念伪代码ApiEncryptannresolveHandlerAnnotation(request);booleanneedReqann!nullann.request();booleanneedRespann!nullann.response();StringencryptHeaderrequest.getHeader(X-Api-Encrypt);if(!needReq!needRespisBlank(encryptHeader)){chain.doFilter(request,response);// 普通接口放行return;}// POST/PUT/DELETE有加密头则包装解密标注了 request 却没头 → 参数错误if(isWriteMethodisNotBlank(encryptHeader)){requestnewDecryptRequestWrapper(request,decryptor);}elseif(needReq){throwinvalidParam(请求未包含加密标头);}if(needResp){responsenewEncryptResponseWrapper(response);// 先包着链尾再真正加密}chain.doFilter(request,response);// 链结束后若 needResp把缓冲内容加密写回并打上加密响应头要点注解驱动 请求头双保险前端必须带加密头后端方法必须声明需要解密避免「误加密普通上传」或「漏加密敏感口」。只处理写方法 BodyGET 通常无 Body加密主要打在 JSON POST。算法可配置AES对称性能好或 RSA非对称密钥角色对调要小心。配置算法、密钥、请求头配置项语义勿把密钥提交进 Git项含义enable总开关关闭则整条 Filter 可短路header默认X-Api-Encrypt请求/响应共用语义algorithmAES或RSA国密 SM2/SM4 可二次扩展requestKey后端用来解密请求的钥responseKey后端用来加密响应的钥AES vs RSA密钥角色别搞反算法后端 requestKey前端请求加密用后端 responseKey前端响应解密用AES共享密钥同一共享密钥共享密钥可与请求同或不同对应共享密钥RSA私钥公钥公钥私钥AES 密钥长度要对齐实现常见 16/32 字节前端 CryptoJS ECB PKCS7 必须与后端 Hutool AES 模式一致否则「能加密不能解密」。前端Vue3 RequestClient 怎么接RuoyiOffice web-antd 在 axios 封装里挂了加解密工具constapiEncryptcreateApiEncrypt(import.meta.env);// 请求拦截按调用方标记加密if((config.headers||{}).isEncrypt){config.dataapiEncrypt.encryptRequest(config.data);config.headers[apiEncrypt.getEncryptHeader()]true;}// 响应拦截后端打了加密头则先解密再交给业务constencryptHeaderapiEncrypt.getEncryptHeader();if((response.headers[encryptHeader]true||response.headers[encryptHeader.toLowerCase()]true)typeofresponse.datastring){response.dataapiEncrypt.decryptResponse(response.data);}业务侧敏感调用awaitrequestClient.post(/system/user/profile/update-password,data,{headers:{isEncrypt:true},});环境变量里配置与后端一致的算法、header 名、请求加密钥、响应解密钥。生产密钥走私密配置/CI Secret禁止写进公开仓库的.env.example真值。和「字段加密」「API 签名」怎么分工浏览器 ──(1 传输加密)──▶ API ──(2 签名校验)──▶ Service ──(3 字段加密)──▶ DB ApiEncrypt appIdsign TypeHandler问法该用谁Charles 里密码是明文传输加密别人改了金额字段重放签名 时效 nonce备份 SQL 里手机号裸奔字段加密 / 脱敏展示双击提交两单幂等Idempotent不是加密加密解决「看不懂」签名解决「改不了、重放难」幂等解决「做两次等于做一次」——别指望一个注解包打天下。对比落库加密架构另一条线落地清单与踩坑上线前核对前后端algorithm/ header 名一致AES 模式与 padding 一致ECB/CBC 混用必炸RSA 公私钥角色按上表对齐仅敏感接口开isEncrypt大文件上传、multipart不要整包 AES网关/Nginx 勿二次改写 Body 编码访问日志若打印 Body注意打的是解密前还是解密后合规密钥轮换预案双钥窗口期或强制客户端升级常见故障现象排查后端报「未包含加密标头」前端没带isEncrypt或 header 名不一致解密结果为空密钥错、算法错、或前端加密了已经是字符串的二次 JSON响应业务码解析失败响应拦截器没先解密把密文当 JSON parse本地 Postman 调不通要用脚本先加密 Body或临时关该接口注解勿关生产总开关文件上传 400multipart 被当成 JSON 解密——排除加密FAQQ1全站所有接口都加密会不会很慢AAES 对 JSON 级别开销通常可接受全站加密会让排障、开放 API、第三方回调变地狱。建议登录改密、支付相关、证件号提交等点状开启。Q2为什么 Filter 要在「有注解却无加密头」时直接失败A防止攻击者去掉加密头、企图走明文旁路也防止前端漏配却「看起来成功」造成假安全感。Q3和国密 SM4/SM2A扩展点在算法工厂加依赖与加解密器分支即可注解与前端isEncrypt协议可复用。Q4微服务 / 网关要解密几次A推荐在业务服务入口解密一次网关只做 TLS 与鉴权避免双端持钥扩散。若网关必须看到明文做路由再评估「网关终止加密 mTLS 到后端」。Q5响应也加密后前端错误提示怎么办A全局异常仍返回统一 Result只要 Filter 在写出前加密、前端先解密错误码体验与明文接口一致。和 RuoyiOffice 的对应关系能力位置概念ApiEncrypt FilterWeb Starter · encrypt 包加解密配置api-encrypt配置项enable/header/algorithm/keys前端工具vben/utils·createApiEncrypt请求封装apps/web-antd·api/request.ts对照字段加密MyBatis TypeHandler对照API 签名签名设计专题完整后端GitCode / AtomGit前端GitCode · vben总结HTTPS ≠ 抓包安全敏感 Body 需要应用层加解密。ApiEncrypt Filter让 Controller 继续写明文 VO密钥与算法集中配置。Vue3 用isEncrypt点状开启响应头驱动解密避免全站误伤。与字段加密、签名、幂等正交组合才是企业接口安全的完整拼图。下一篇换业务编排视角审批红点、短信、邮件如何用「场景 × 渠道 × WebSocket」一次性打穿。⭐ GitCode · AtomGit 点星夏日活动攒积分。在线体验RuoyiOffice商业版源码授权联系页 · 企业微信RuoyiOffice关键词ApiEncrypt、AES、RSA、Vue3 请求加密、Spring Boot 3 Filter、X-Api-Encrypt、接口传输安全、防抓包