安全地存储客户机密
Store client secret securely
我知道 public client shouldn't use a client secret because, no matter how much you obfuscate it, it won't be protected from reverse engineering.
但是,我正在验证的服务的负责人不希望to/can不更改它。因此,我需要存储客户端机密并尽可能保护它免受逆向工程。
所以,我想到了在构建时使用 gradle 加密它并将其存储在一个文件中。然后,当我在 运行 需要它时,我会解密它。但现在我必须解决如何存储加密密钥的问题...
我不太了解安全性,所以,我不知道这是否可以解决,或者 Android (min sdk 15) 是否为这种情况提供任何机制。
有什么想法吗?
正如你所说,无论你做什么,你多么想隐藏你的密钥,你都不可能 100% 隐藏它。
但是,如果你想让逆向工程师的工作更难;
首先混淆你的客户(我想你已经这样做了)。
其次,不要把你的密钥硬编码到客户端。登录或用户打开应用程序后收到密钥。并通过 SSL 将密钥传递给客户端。将秘密存储为字节数组,不要将其保存到客户端中。存入内存即可。
这些步骤并不能保证密钥的安全,反而使逆向工程师的工作变得非常困难。
您也可以尝试Dexguard混淆和加密数据。 Dexguard 是由开发 proguard 的同一个人制作的。
This article 建议这些选项,从不太安全到更安全:
以明文形式存储
使用对称密钥加密存储
使用 Android 密钥库
使用非对称密钥加密存储
可能,结合使用#4 和某种方式来明确识别设备会足够安全
也许最好的选择是使用 NDK 因为它不能被反编译,就像 Godfrey Nolan 点 here
这是我发现有用的资源,可以帮助我实现它link to the resource
干杯
@Semih 的回答是正确的。密钥部分是需要扩展的部分。
- 密钥在应用程序和网关服务器之间,而不是底层服务。
- 网关服务器负责将该密钥转换为特定于服务的内容。
登录过程完成后使用以下内容构建密钥
- 服务器生成客户端登录专用的密钥对。
- 发送服务器的 public 密钥用于客户端登录专用的加密
- 应用程序会为自己的目的生成密钥对
- 应用程序将发送使用服务器的 public 密钥加密的 public 密钥
- 服务器将验证 public 密钥是否使用其 public 密钥签名。
任何未来的请求都将涉及以下内容
所有从客户端发送到服务器的数据都将使用 JWT 加密,消息将由应用程序的私钥签名并使用服务器的 public 密钥加密。
问题是确保#1 任何人都可以登录并启动流程,那么您将如何防止这种情况发生?我能想到的唯一方法是对登录进行验证码检查。
该解决方案将客户端机密的存储推送到服务器而不是应用程序本身,并使用应用程序的凭据保护它。
我知道 public client shouldn't use a client secret because, no matter how much you obfuscate it, it won't be protected from reverse engineering.
但是,我正在验证的服务的负责人不希望to/can不更改它。因此,我需要存储客户端机密并尽可能保护它免受逆向工程。
所以,我想到了在构建时使用 gradle 加密它并将其存储在一个文件中。然后,当我在 运行 需要它时,我会解密它。但现在我必须解决如何存储加密密钥的问题...
我不太了解安全性,所以,我不知道这是否可以解决,或者 Android (min sdk 15) 是否为这种情况提供任何机制。
有什么想法吗?
正如你所说,无论你做什么,你多么想隐藏你的密钥,你都不可能 100% 隐藏它。 但是,如果你想让逆向工程师的工作更难;
首先混淆你的客户(我想你已经这样做了)。
其次,不要把你的密钥硬编码到客户端。登录或用户打开应用程序后收到密钥。并通过 SSL 将密钥传递给客户端。将秘密存储为字节数组,不要将其保存到客户端中。存入内存即可。
这些步骤并不能保证密钥的安全,反而使逆向工程师的工作变得非常困难。
您也可以尝试Dexguard混淆和加密数据。 Dexguard 是由开发 proguard 的同一个人制作的。
This article 建议这些选项,从不太安全到更安全:
以明文形式存储
使用对称密钥加密存储
使用 Android 密钥库
使用非对称密钥加密存储
可能,结合使用#4 和某种方式来明确识别设备会足够安全
也许最好的选择是使用 NDK 因为它不能被反编译,就像 Godfrey Nolan 点 here
这是我发现有用的资源,可以帮助我实现它link to the resource
干杯
@Semih 的回答是正确的。密钥部分是需要扩展的部分。
- 密钥在应用程序和网关服务器之间,而不是底层服务。
- 网关服务器负责将该密钥转换为特定于服务的内容。
登录过程完成后使用以下内容构建密钥
- 服务器生成客户端登录专用的密钥对。
- 发送服务器的 public 密钥用于客户端登录专用的加密
- 应用程序会为自己的目的生成密钥对
- 应用程序将发送使用服务器的 public 密钥加密的 public 密钥
- 服务器将验证 public 密钥是否使用其 public 密钥签名。
任何未来的请求都将涉及以下内容
所有从客户端发送到服务器的数据都将使用 JWT 加密,消息将由应用程序的私钥签名并使用服务器的 public 密钥加密。
问题是确保#1 任何人都可以登录并启动流程,那么您将如何防止这种情况发生?我能想到的唯一方法是对登录进行验证码检查。
该解决方案将客户端机密的存储推送到服务器而不是应用程序本身,并使用应用程序的凭据保护它。