szandy6
V2EX  ›  问与答

客户端签名密钥如何存储才能保证安全?

  •  
  •   szandy6 · Aug 22, 2023 · 2888 views
    This topic created in 1026 days ago, the information mentioned may be changed or developed.

    客户端请求 API 时,一般要带上签名信息,签名参数用的密钥( secret key)怎么存储才能保证安全,还是说有其他更好的方案,比如放在服务端,大家一般是怎么做的。

    Supplement 1  ·  Aug 22, 2023
    在网上也看到很多人说 https 环境下,没必要在对参数进行签名,国外很多大厂的 Open API 都是没有签名的,这种说法很有道理,我也挺赞同的。但在国内,没有几个大厂的 Open API 是不签名的。
    30 replies    2023-08-23 15:46:42 +08:00
    dzdh
        1
    dzdh  
       Aug 22, 2023
    webauthn ?
    EchoAI
        2
    EchoAI  
       Aug 22, 2023 via Android
    我们目前是这么做的:Android 使用 so 文件,iOS 使用 a 文件,web 使用 wasm 文件。密钥和算法都在内部实现,同时做了很多防反编译的策略。
    szandy6
        3
    szandy6  
    OP
       Aug 22, 2023
    @EchoAI 我们之前也是这么干的,不过安全部门说会被反编译出来。
    EchoAI
        4
    EchoAI  
       Aug 22, 2023
    只要是密钥需要存储在客户端,就会被拿出来。只是时间的问题。绝对的安全是不存在的。
    szandy6
        5
    szandy6  
    OP
       Aug 22, 2023
    @EchoAI 是的,能做的就是提高一点破解的复杂度,没有绝对安全。
    tool2d
        6
    tool2d  
       Aug 22, 2023
    我看到过的版本是密钥和时间强相关,客户端 6 小时就会变动一次,用算法生成的。

    要破解密钥容易,要拿到算法还是有一点难度的。
    0o0O0o0O0o
        7
    0o0O0o0O0o  
       Aug 22, 2023 via iPhone
    先说观点:放在客户端的全部都是能够被公开的东西。

    > 安全部门说会被反编译出来

    一些白盒密码方案大约就是为了应付这种情况,说是应付,因为它们和 #2 在一部分攻击者看来没有太多本质区别。
    xiangyuecn
        8
    xiangyuecn  
       Aug 22, 2023
    http 时代的遗留产物。
    yinmin
        9
    yinmin  
       Aug 22, 2023 via iPhone
    一了百了的方案是改成不对称加密。客户端保存 rsa 公钥(是公开的,没必要保密),客户端用 rsa 公钥加密数据后上传,服务器用 rsa 用私钥解密。

    直接从理论上解决问题。
    edwardhodges
        10
    edwardhodges  
       Aug 22, 2023
    客户端不要直接请求这个 API 。客户端请求自己的业务服务器,然后服务器来请求这个 API ,密钥放在服务器就好了。
    tool2d
        11
    tool2d  
       Aug 22, 2023
    @yinmin 不行哦,客户端能用 rsa 公钥加密,那么黑客也能用 rsa 公钥加密。

    服务器收到后,都能解密。分不清哪个是黑客签名,哪个是真客户端签名。
    mdn
        12
    mdn  
       Aug 22, 2023
    @edwardhodges 业务服务器如何分辨是自己的客户端了
    hsfzxjy
        13
    hsfzxjy  
       Aug 22, 2023
    放在系统原生的钥匙串应该安全吧?比如安卓的 https://developer.android.com/reference/android/security/KeyChain
    szandy6
        14
    szandy6  
    OP
       Aug 22, 2023
    @yinmin HMAC 与加密需求不一样,如果是数据加密,现在非对称加密是比较成熟的方案。
    SteveRogers
        15
    SteveRogers  
       Aug 22, 2023 via iPhone
    密钥本地二次加密、二加密后的密钥分开存储,然后放到多处。
    xiaoke
        16
    xiaoke  
       Aug 22, 2023 via Android
    搭车请教,看到一些安卓 APP 直接把证书文件放在 assets 目录下,有风险吗?
    0o0O0o0O0o
        17
    0o0O0o0O0o  
       Aug 22, 2023 via iPhone
    @tool2d #11 你说的这是客户端软件层面 **无解** 的事情(包括白盒),客户端的所有混淆都可以被分析所有逻辑都可以被模拟,只是难易度的区别。

    > 分不清哪个是黑客签名,哪个是真客户端签名

    这对应的应该是一个完整的风控系统,而不单纯是客户端该考虑的
    iX8NEGGn
        18
    iX8NEGGn  
       Aug 22, 2023 via iPhone
    你没搞明白,国内大厂的 api 签名是为了防止重放攻击,参与签名的参数一般都包含时间,你这个属于 SSL Pinning ,为了提升绕过客户端请求的难度,破解是避免不了的,只是增加破解难度而已。
    rocmax
        19
    rocmax  
       Aug 22, 2023 via Android   ❤️ 1
    一般应用加密只是为了防止篡改请求。如果你的应用真的需要用签名核实身份(例如比特币钱包类),请使用 HSM 。如果是手机应用的话内置加密模块有类似功能,可以保证密钥不离开硬件。
    edwardhodges
        20
    edwardhodges  
       Aug 23, 2023
    @mdn 已经是业务服务器了,那就可以设置自己的登录等业务了。登录后获取 token ,用 token 来做校验不是常规操作?
    mdn
        21
    mdn  
       Aug 23, 2023
    @edwardhodges #20 客户端加签名在没有被破解的情况下都是 信任的客户端,token 无法证明是客户端请求的 API
    edwardhodges
        22
    edwardhodges  
       Aug 23, 2023
    @mdn 是不是想复杂了。这个跟客户端没有什么关系吧,举个例子,token 根据手机号登录验证后获取,然后根据当前用户的 token 来请求业务服务器。业务服务器根据这个 token 判断是哪个用户,然后业务服务器再来调用比如 openai 的接口。就是说使用 secret key 调用三方 api 的行为是发生在自己服务器的。 而客户端的验证方式就是传统的验证方式,所有 app 都是这么进行的。 客户端就是被破解了又怎么样,最多知道了 api 接口(客户端里面没有保存三方的 secret key 这些信息),那又怎么样。
    CodeCodeStudy
        23
    CodeCodeStudy  
       Aug 23, 2023
    @yinmin #9 非对称加密太慢了,不应直接用非对称加密数据,而是用非对称加密对称加密的密钥,然后用对称加密数据
    mdn
        24
    mdn  
       Aug 23, 2023
    @edwardhodges #22 客户端加签名,想要防止某些用户绕过客户端直接请求接口,比如签到等功能,token 用户自己也能看到,签名需要用户破解
    IvanLi127
        25
    IvanLi127  
       Aug 23, 2023 via Android
    签名是防谁篡改负载?防非法用户篡改用登录凭据,防网络链路爱咋存咋存,防合法用户那得靠硬件了。
    msg7086
        26
    msg7086  
       Aug 23, 2023
    @tool2d #11
    > 分不清哪个是黑客签名,哪个是真客户端签名。

    要不然呢?难道你还能分清你对面的是客户端还是黑客?
    EchoAI
        27
    EchoAI  
       Aug 23, 2023 via Android
    @edwardhodges #22 客户端被破解了,不仅知道了 API ,用户的 token 也能被拿到,还省得去破解密钥了,直接使用 token 请求 API 就可以了。
    tool2d
        28
    tool2d  
       Aug 23, 2023
    @msg7086 你普通 ssh 连接,服务器可以设置客户端指纹的白名单。就算黑客有密码和密钥,只要客户端指纹不对,服务器也是可以拒绝请求的。

    客户端被挟持发请求,和黑客第三方 IP 发起恶意请求,对服务器来说,还是有区别的。
    edwardhodges
        29
    edwardhodges  
       Aug 23, 2023
    又看了下讨论,如果想把请求绝对限制在自己指定的客户端里,理论上只能增加难度,无法绝对的。不清楚大家的需求,感觉这个需求本身意义就不大吧。 使用加固混淆等方式,增加客户端 app 被破解的难度,所有请求必须使用信任机构颁发的证书的 https ,不在客户端存放重要的信息,验证流程通过服务器来校验。这些操作下来,理论上已经很安全了吧。
    msg7086
        30
    msg7086  
       Aug 23, 2023
    @tool2d 客户端可以视作开源,黑客直接伪造指纹就行了。
    有些时候是不需要从头开始搞的,拿现成的代码来植入点东西跑可能会更方便。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2565 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 857ms · UTC 01:09 · PVG 09:09 · LAX 18:09 · JFK 21:09
    ♥ Do have faith in what you're doing.