我正在使用AWS Cognito,我需要在我的Android应用程序中的某处存储一些凭据和机密,以便稍后使用它们来登录/注册/注销用户。
一些消息来源建议将凭证存储在项目gradle.properties文件中。从那里,凭证将被检索为BuildConfig.FIELD_NAME
。我可以100%确定在逆向工程时无法从apk中提取这些内容吗?
我想到的另一种方法是使用非对称加密算法(使用公钥 - 私钥)加密凭证,并在需要时在运行时解密它们,但同样,我需要在我的应用程序内部存储公钥以解密证书。这不再起作用,因为可以提取反编译apk的公钥。
我已经做了很多研究,但在这种情况下我找不到任何帮助。几乎每篇文章都指的是如何存储密码等凭证,但这不是相同的情况,因为我没有从服务器或运行时的任何地方检索我的秘密和凭据。进行API调用以获取凭据再次是一件坏事。
那么,我怎样才能尽可能安全地做到这一点?我在等你的解决方案!谢谢
编辑:密钥库并没有真正起作用,因为在将它们添加到密钥库之前我必须从某处获取秘密
这实际上取决于您需要或希望您的应用程序的安全性,以及这些凭据的敏感程度。由于无法从服务器端存储和检索它们,因此最好的办法是将它们嵌入到代码中的某个位置。 APK可以很容易地被反编译,因此您的凭据将始终以某种方式可访问。真正的问题是您希望逆转过程有多难。
从那里,凭据将作为BuildConfig.FIELD_NAME检索。我可以100%确定在逆向工程时无法从apk中提取这些内容吗?
我100%肯定它可以被检索:)。 Java不会加密任何字符串,它们都将作为原始文本存储在dex文件中,随时可以进行grep。
从那里开始,接下来的步骤是使用静态密钥加密代码中的密钥。有些工具会为你做这些,比如DexGuard,Dasho,Dexprotector - 你也可以拿出自己的解决方案.This article解释得很好。
请记住,您自己的解决方案或第三方工具提供的解决方案可能很容易逆转:请参阅qxxswpoi for DexGuard。还请注意,在运行时解密时,这些凭据将在设备的RAM中清除,从而允许调试器轻松读取它们。
你的下一个最好的选择是使用本机代码中的加密字符串:更难以反向和追踪,但仍然可行。
然后,您可以使用白盒加密技术,再次使用Inside Secure提议的第三方工具。这实际上将加密算法和密钥混合到混淆的本机代码中,这可能使您难以反向和难以调试加密/解密方法。在这里,您只需在应用中包含加密凭据,它们将在白盒内安全解密。白盒通常非常安全(但不是不可能破解),但一旦解密,凭证将在设备的内存中清晰显示。这样可以更彻底地防止简单的反编译。
然后......如果不涉及硬件解决方案(KeyStore,嵌入式安全元素)和服务器来支持所有内容,我认为你不能做得更远。