【问题标题】:Store client secret securely安全地存储客户端机密
【发布时间】:2015-04-20 23:36:30
【问题描述】:

我知道public client shouldn't use a client secret,因为无论你如何混淆它,它都不会受到reverse engineering 的保护。

但是,负责我正在验证的服务的人员不想/不能更改它。因此,我需要存储客户端密码,并尽可能保护它免受逆向工程的影响。

所以,我想在构建时使用 gradle 对其进行加密并将其存储在一个文件中。然后,当我在运行时需要它时,我会解密它。但是现在我要解决如何存储加密密钥的问题......

我对安全性了解不多,所以不知道能不能解决这个问题,或者Android(min sdk 15)是否为这种场景提供了任何机制。

有什么想法吗?

【问题讨论】:

标签: android security encryption oauth secret-key


【解决方案1】:

This article 建议这些选项,从少到更安全:

  1. 以明文形式存储

  2. 使用对称密钥加密存储

  3. 使用 Android 密钥库

  4. 使用非对称密钥加密存储

可能,结合使用 #4 和某种方式来明确识别设备会足够安全

【讨论】:

    【解决方案2】:

    也许最好的选择是使用NDK,因为它不能被反编译,就像Godfrey Nolan 点here

    这是一个我发现有用的资源,可以帮助我实现它link to the resource

    干杯

    【讨论】:

    • 不能反编译并不意味着不能检查:本机代码可以被反汇编成接近编译器生成的汇编指令。它比高级代码更难阅读,但它仍然是代码。
    【解决方案3】:

    正如您所说,无论您做什么,您如何尝试隐藏您的密钥,您都无​​法 100% 隐藏它。 但是,如果你想让逆向工程师的工作更加努力;

    首先混淆你的客户(我猜你已经这样做了)。

    其次,不要将您的密钥硬编码到客户端中。登录或用户打开应用程序后接收密钥。并通过 SSL 将密钥传递给客户端。将秘密存储为字节数组,不要将其保存到客户端中。只是存储在内存中。

    这些步骤并不能保证密钥的安全,反而会让逆向工程师的工作变得非常困难。

    【讨论】:

    • 这一定是最糟糕的建议了。
    • 其实这个建议还不错。虽然秘密应该在应用程序和主网关之间,而不是在其他服务之间。不过,我不想过多更改答案,所以我会单独发布一个。
    • @Johny19 为什么你认为这很糟糕?
    【解决方案4】:

    您也可以尝试Dexguard 对数据进行混淆和加密。 Dexguard 是由开发 proguard 的同一个人制作的。

    【讨论】:

      【解决方案5】:

      @Semih 的回答是正确的。密钥部分是需要扩展的。

      1. 密钥在应用程序和网关服务器之间,而不是在底层服务之间。
      2. 网关服务器负责将该密钥转换为特定于服务的密钥。

      登录过程完成后使用以下密钥构建密钥

      1. 服务器生成一个特定于客户端登录的密钥对。
      2. 发送服务器的公钥以进行特定于客户端登录的加密
      3. 该应用会为自己的目的生成一个密钥对
      4. 应用程序将发送使用服务器公钥加密的公钥
      5. 服务器将验证公钥是否已使用其公钥签名。

      任何未来的请求都将涉及以下内容

      从客户端发送到服务器的所有数据都将使用 JWT 加密,消息将由应用的私钥签名并使用服务器的公钥加密。

      问题是确保 #1 任何人都可以登录并启动该过程,那么您将如何防止这种情况发生?我能想到的唯一方法是在登录时进行 CAPTCHA 检查。

      该解决方案将客户端机密的存储推送到服务器而不是应用本身,并使用应用的凭据对其进行保护。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-24
        • 2021-12-02
        • 1970-01-01
        • 2012-10-29
        • 1970-01-01
        • 2017-01-24
        相关资源
        最近更新 更多