敏感 API 需要加密请求体避免泄漏请求内容给 CDN,是否使用了 AES-256-GCM 这类带完整性验证的加密算法,就没有必要再签名一次了?或者有没有更简单的方案, HMAC 拼接签名客户嫌麻烦不太愿意对接 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
drymonfidelia
V2EX    信息安全

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

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

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

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

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

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

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

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

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

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

    既然是客户,你得提供 sdk ,让他调
    常用的 c java go node rust swift oc Kotlin python 鸿蒙 ts php
    shoaly
        37
    shoaly  
       175 天前
    @ysc3839 #34 公钥 不需要加密, 泄漏了也没事, 直接敞开了放官网首页 都可以, 甚至说可以所有用户共用同一个公钥也没问题
    ysc3839
        38
    ysc3839  
       175 天前 via Android
    @shoaly 问题是防不了中间人攻击,中间人可以把公钥替换掉,然后就能用他自己的私钥解密数据。
    shoaly
        39
    shoaly  
       175 天前
    @ysc3839 #38 他原文只是想要 避免被中间人看到内容, 如果中间人已经坏到要替换内容的程度, 这还不直接跑了, 等什么呢?
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     4818 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 46ms UTC 09:48 PVG 17:48 LAX 02:48 JFK 05:48
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86