敏感 API 需要加密请求体避免泄漏请求内容给 CDN,是否使用了 AES-256-GCM 这类带完整性验证的加密算法,就没有必要再签名一次了?或者有没有更简单的方案, HMAC 拼接签名客户嫌麻烦不太愿意对接

2025 年 4 月 17 日
 drymonfidelia
所有人都知道 CDN 为了缓存请求需要卸载 SSL ,可以接触到明文 Payload 。但是我们的产品需要接触敏感数据,例如实名认证、信用卡之类的信息,需要让 CDN 无法解密请求,同时尽可能简单
例如所有 API 都只带一个 X-AppId 请求头用于 API 服务器获取该 App 对应的 AES 密钥,然后用这个 AES 密钥加密请求体。用户创建 APP 的时候把这个密钥返回给客户端。足够安全了吗?
我想到的缺点是如果服务器被脱裤,所有密钥全泄漏了,要联系所有客户换密钥。
3902 次点击
所在节点    信息安全
39 条回复
yinmin
2025 年 4 月 17 日
防脱库就用 ecc 不对称加密,用户事先上传 ecc 公钥,数据库保存的是 ecc 公钥。

api 调用时,x-appid 是用户的 guid ,body 是 ecc 私钥加密的(其实是 ecc 私钥加密随机 key ,然后随机 key 使用 aes 加密 body )

脱库获得 ecc 公钥也没法伪造。
drymonfidelia
2025 年 4 月 17 日
@yinmin 考虑过非对称加密,问题是如果 payload 比较大(最大可能几十 MB ),用非对称会不会太慢了
drymonfidelia
2025 年 4 月 17 日
@yinmin cc 私钥加密随机 key ,然后随机 key 使用 aes 加密 body 这个有现成的实现么,还是需要自己随机生成 32bytes ,ECC 加密后拼接
ccpp132
2025 年 4 月 17 日
非对称可以加密一个临时随机密钥,再用这个密钥加对称算法来加密 payload ,然后拼一起发就行了
v1
2025 年 4 月 17 日
有舍有得,不可能快速又安全
drymonfidelia
2025 年 4 月 17 日
@ccpp132
@kk2syc
@yinmin 我想到一种方案,用户需要先调用 Auth 接口使用 RSA4096 加密注册 AES 密钥,然后 API 服务器将 AES 密钥存入 redis ,之后的请求都通过这个 AES 密钥验证,万一被拖库了我只要 purgeall 就可以,不知道是否足够安全
yinmin
2025 年 4 月 17 日
#3 ”私钥加密随机 key ,然后随机 key 使用 aes 加密 body” 是 标准的加密方案。

给一个具体思路,详细情况问 gpt-4o/claude 3.7:
方案一: 使用 openssl 生成 ecc256 的公钥和密钥文件,然后提供 java 、c#、python 的产生公钥/私钥对、加密/解密、签名/验证签名的代码

方案二: 请使用 wireguard 的公钥和私钥对的格式,提供 java 、c#、python 的产生公钥/私钥对、加密/解密、签名/验证签名的代码

有了代码后,测试一下不同开发语言的兼容性,选择一种方案即可。
yinmin
2025 年 4 月 17 日
@drymonfidelia #6 别用 rsa4096 又长又慢。 用 openssl ecc256+AES 或者 wireguard 的 X25519+ChaCha20-Poly1305 。

另外,这个公钥/密钥对是创建客户的时候产生的,永久保存,服务器只保存公钥,私钥给客户(如果涉及资金,建议由用户生成公钥/密钥对,然后上传公钥)。别临时产生存 redis ,没意义的。我说的方案是银行数据互联级别的,安全性很高的。
yinmin
2025 年 4 月 17 日
如果涉及资金,考虑到 5-10 年之后安全性,可选 openssl 的 ecc384+aes256 算法,如果不涉及资金,#8 的 2 种算法都可以。
yinmin
2025 年 4 月 17 日
如果是信创相关,就选 sm2+sm4
cnbatch
2025 年 4 月 17 日
简单粗暴解决办法:敏感数据走直连,不经 CDN
KagurazakaNyaa
2025 年 4 月 17 日
临时生成+ecdh 之类的密钥交换那是因为没有可信的信道进行密钥交换,你这可以让用户直接用可信信道给公钥为啥还需要临时生成存到 redis 里?
你直接每个请求的 payload 的前 32 字节都是用用户注册过的公钥加密的一个 nonce ,作为 aes key 加密后续的 payload
客户端用本地的私钥解密前 32 个字节,作为 aes key 解密后续的 payload
hanyuwei70
2025 年 4 月 17 日
首先你们这个需求是不是涉及到合规?涉及合规的话请咨询法务。
其次如果确实需要可以跑两层 TLS ,不太建议自己弄一套加密,容易出事。
ysc3839
2025 年 4 月 17 日
如果信任 CDN 不会进行中间人攻击,只是为了避免数据无意间泄漏的话,这种方案可行。
billccn
2025 年 4 月 17 日
赞同 13 楼,实名认证不知道什么机构管,信用卡的话,你这种自创的加密用法+无法保证 perfect forward secrecy 肯定不能通过 PCI DSS ,谁用你们系统谁倒霉。
drymonfidelia
2025 年 4 月 17 日
@ysc3839 我想问的就是按我标题里的这种方法,因为 GCM 模式支持消息完整性校验,CDN 最多也只能进行重放攻击吧?
mayli
2025 年 4 月 17 日
感觉这个是的反模式了
敏感 api 肯定不能给 cdn 解 ssl
正规做法是严格端到端 ssl, 自己实现的难免不合规,不安全,或者实现巨繁琐。
国内还有些做法是有个加密机,厂商也有合规流程和 sdk.
尽量别自己发明加密流程实现,出了问题锅背不起
mayli
2025 年 4 月 17 日
就比如,你现在这个架构能挡住 replay attack 吗?
mooyo
2025 年 4 月 17 日
敏感 API 不上 CDN 不就行了,感觉是个 A-B 问题,你们为什么要给敏感 API 上 CDN ?
ysc3839
2025 年 4 月 17 日
@drymonfidelia 还可以进行中间人攻击,把返回的密钥替换掉就行。这种情况下,你的数据对于 CDN 就相当于明文传输。
另外楼上很多人在那分析怎么实现完全没必要,要在不可信通道保证安全的话,必须依赖可信的第三方(比如在 https 中就是颁发证书的 CA),任何不依赖可信第三方的方案都不能完全保证安全。
同时考虑到自己实现加密算法复杂且不安全,较好的方案是把 CDN 当 http proxy 用,里面再建立标准的 https 连接,连接到内网的某个服务器,服务器也要正常配置 https 证书。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1126288

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX