安全地存储客户端机密
Posted
技术标签:
【中文标题】安全地存储客户端机密【英文标题】: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)是否为这种场景提供了任何机制。
有什么想法吗?
【问题讨论】:
Best Practice for storing private API keys in Android的可能重复 OAuth secrets in mobile apps的可能重复 【参考方案1】:This article 建议这些选项,从少到更安全:
以明文形式存储
使用对称密钥加密存储
使用 Android 密钥库
使用非对称密钥加密存储
可能,结合使用 #4 和某种方式来明确识别设备会足够安全
【讨论】:
【参考方案2】:也许最好的选择是使用NDK,因为它不能被反编译,就像Godfrey Nolan 点here
这是一个我发现有用的资源,可以帮助我实现它link to the resource
干杯
【讨论】:
不能反编译并不意味着不能检查:本机代码可以被反汇编成接近编译器生成的汇编指令。它比高级代码更难阅读,但它仍然是代码。【参考方案3】:正如您所说,无论您做什么,您如何尝试隐藏您的密钥,您都无法 100% 隐藏它。 但是,如果你想让逆向工程师的工作更加努力;
首先混淆你的客户(我猜你已经这样做了)。
其次,不要将您的密钥硬编码到客户端中。登录或用户打开应用程序后接收密钥。并通过 SSL 将密钥传递给客户端。将秘密存储为字节数组,不要将其保存到客户端中。只是存储在内存中。
这些步骤并不能保证密钥的安全,反而会让逆向工程师的工作变得非常困难。
【讨论】:
这一定是最糟糕的建议了。 其实这个建议还不错。虽然秘密应该在应用程序和主网关之间,而不是在其他服务之间。不过,我不想过多更改答案,所以我会单独发布一个。 @Johny19 为什么你认为这很糟糕?【参考方案4】:您也可以尝试Dexguard 对数据进行混淆和加密。 Dexguard 是由开发 proguard 的同一个人制作的。
【讨论】:
【参考方案5】:@Semih 的回答是正确的。密钥部分是需要扩展的。
-
密钥在应用程序和网关服务器之间,而不是在底层服务之间。
网关服务器负责将该密钥转换为特定于服务的密钥。
登录过程完成后使用以下密钥构建密钥
-
服务器生成一个特定于客户端登录的密钥对。
发送服务器的公钥以进行特定于客户端登录的加密
该应用会为自己的目的生成一个密钥对
应用程序将发送使用服务器公钥加密的公钥
服务器将验证公钥是否已使用其公钥签名。
任何未来的请求都将涉及以下内容
从客户端发送到服务器的所有数据都将使用 JWT 加密,消息将由应用的私钥签名并使用服务器的公钥加密。
问题是确保 #1 任何人都可以登录并启动该过程,那么您将如何防止这种情况发生?我能想到的唯一方法是在登录时进行 CAPTCHA 检查。
该解决方案将客户端机密的存储推送到服务器而不是应用本身,并使用应用的凭据对其进行保护。
【讨论】:
以上是关于安全地存储客户端机密的主要内容,如果未能解决你的问题,请参考以下文章