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

防脱库就用 ecc 不对称加密,用户事先上传 ecc 公钥,数据库保存的是 ecc 公钥。

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

脱库获得 ecc 公钥也没法伪造。

考虑过非对称加密,问题是如果 payload 比较大(最大可能几十 MB ),用非对称会不会太慢了

cc 私钥加密随机 key ,然后随机 key 使用 aes 加密 body 这个有现成的实现么,还是需要自己随机生成 32bytes ,ECC 加密后拼接

非对称可以加密一个临时随机密钥,再用这个密钥加对称算法来加密 payload ,然后拼一起发就行了

有舍有得,不可能快速又安全

我想到一种方案,用户需要先调用 Auth 接口使用 RSA4096 加密注册 AES 密钥,然后 API 服务器将 AES 密钥存入 redis ,之后的请求都通过这个 AES 密钥验证,万一被拖库了我只要 purgeall 就可以,不知道是否足够安全

#3 ”私钥加密随机 key ,然后随机 key 使用 aes 加密 body” 是 标准的加密方案。

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

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

有了代码后,测试一下不同开发语言的兼容性,选择一种方案即可。

#6 别用 rsa4096 又长又慢。 用 openssl ecc256+AES 或者 wireguard 的 X25519+ChaCha20-Poly1305 。

另外,这个公钥/密钥对是创建客户的时候产生的,永久保存,服务器只保存公钥,私钥给客户(如果涉及资金,建议由用户生成公钥/密钥对,然后上传公钥)。别临时产生存 redis ,没意义的。我说的方案是银行数据互联级别的,安全性很高的。

如果涉及资金,考虑到 5-10 年之后安全性,可选 openssl 的 ecc384+aes256 算法,如果不涉及资金,#8 的 2 种算法都可以。

如果是信创相关,就选 sm2+sm4

简单粗暴解决办法:敏感数据走直连,不经 CDN

临时生成+ecdh 之类的密钥交换那是因为没有可信的信道进行密钥交换,你这可以让用户直接用可信信道给公钥为啥还需要临时生成存到 redis 里?
你直接每个请求的 payload 的前 32 字节都是用用户注册过的公钥加密的一个 nonce ,作为 aes key 加密后续的 payload
客户端用本地的私钥解密前 32 个字节,作为 aes key 解密后续的 payload

首先你们这个需求是不是涉及到合规?涉及合规的话请咨询法务。
其次如果确实需要可以跑两层 TLS ,不太建议自己弄一套加密,容易出事。

如果信任 CDN 不会进行中间人攻击,只是为了避免数据无意间泄漏的话,这种方案可行。

赞同 13 楼,实名认证不知道什么机构管,信用卡的话,你这种自创的加密用法+无法保证 perfect forward secrecy 肯定不能通过 PCI DSS ,谁用你们系统谁倒霉。

我想问的就是按我标题里的这种方法,因为 GCM 模式支持消息完整性校验,CDN 最多也只能进行重放攻击吧?

感觉这个是的反模式了
敏感 api 肯定不能给 cdn 解 ssl
正规做法是严格端到端 ssl, 自己实现的难免不合规,不安全,或者实现巨繁琐。
国内还有些做法是有个加密机,厂商也有合规流程和 sdk.
尽量别自己发明加密流程实现,出了问题锅背不起

就比如,你现在这个架构能挡住 replay attack 吗?

敏感 API 不上 CDN 不就行了,感觉是个 A-B 问题,你们为什么要给敏感 API 上 CDN ?

还可以进行中间人攻击,把返回的密钥替换掉就行。这种情况下,你的数据对于 CDN 就相当于明文传输。
另外楼上很多人在那分析怎么实现完全没必要,要在不可信通道保证安全的话,必须依赖可信的第三方(比如在 https 中就是颁发证书的 CA),任何不依赖可信第三方的方案都不能完全保证安全。
同时考虑到自己实现加密算法复杂且不安全,较好的方案是把 CDN 当 http proxy 用,里面再建立标准的 https 连接,连接到内网的某个服务器,服务器也要正常配置 https 证书。