V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
drymonfidelia
V2EX  ›  信息安全

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

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

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

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

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

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

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

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

    https://chatgpt.com/share/680135e4-f11c-800c-855c-b3afd25ca630
    sinxccc
        24
    sinxccc  
       1 天前
    最简单的方法是找同样合规的 CDN
    yinmin
        25
    yinmin  
       1 天前 via iPhone
    OP 可以问问看有没有类似 sni proxy 的 cdn 。以前去银行开会的时候,听到过有一种 cdn 跑 https 是不需要部署证书的,cdn 不解密数据。
    busier
        26
    busier  
       1 天前 via iPhone   ❤️ 1
    @yinmin sni proxy 就是一 Reverse proxy 而已。连 cdn 的 c 和 d 都做不到,还非要蹭下 cdn 的名号。
    shiji
        27
    shiji  
       1 天前 via iPhone   ❤️ 2
    @sinxccc 对的。 自行创造加密方法是泄密的起点。
    shoaly
        28
    shoaly  
       1 天前
    楼上那么多在说啥? 比如请求体包在一个 json 里面, 直接 用 rsa 公钥加密 然后丢给网关, 网关解密就可以了啊? 哪怕裸的 http 报文在公网传输都是安全的
    ysc3839
        29
    ysc3839  
       1 天前 via Android
    @XiLingHost 目前的问题之一就是没有安全信道,数据对 CDN 来说是明文的
    ysc3839
        30
    ysc3839  
       1 天前 via Android
    @shoaly 那 RSA 公钥如何获得呢?
    shoaly
        31
    shoaly  
       1 天前
    @ysc3839 #30 公钥从你的 https 网站生成好了, 用户登录后台, 自己去领的啊.
    XiLingHost
        32
    XiLingHost  
       1 天前
    @ysc3839 你用户创建 app 的时候写进去不就好了
    msg7086
        33
    msg7086  
       1 天前
    单独开一个 secure 子域名做端到端加密连接不行吗?让 CDN 只做数据反代不就行了。
    TLS 自己已经足够安全了,中间人拿不到数据的。
    ysc3839
        34
    ysc3839  
       1 天前 via Android
    @shoaly @XiLingHost 这么做还是依赖一个安全信道,如果确认是有安全信道,那用楼主提出的方案就够了。现在的问题就是没有安全信道。
    liuidetmks
        35
    liuidetmks  
       1 天前
    HMAC 拼接签名客户嫌麻烦不太愿意对接

    ------------

    既然是客户,你得提供 sdk ,让他调
    常用的 c java go node rust swift oc Kotlin python 鸿蒙 ts php
    shoaly
        37
    shoaly  
       22 小时 56 分钟前
    @ysc3839 #34 公钥 不需要加密, 泄漏了也没事, 直接敞开了放官网首页 都可以, 甚至说可以所有用户共用同一个公钥也没问题
    ysc3839
        38
    ysc3839  
       22 小时 44 分钟前 via Android
    @shoaly 问题是防不了中间人攻击,中间人可以把公钥替换掉,然后就能用他自己的私钥解密数据。
    shoaly
        39
    shoaly  
       22 小时 39 分钟前
    @ysc3839 #38 他原文只是想要 避免被中间人看到内容, 如果中间人已经坏到要替换内容的程度, 这还不直接跑了, 等什么呢?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2660 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 13:07 · PVG 21:07 · LAX 06:07 · JFK 09:07
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.