如何保护 API 密钥免受恶意攻击者反编译我的应用程序以及检测恶意使用?

How can I keep an API key secure from malicious attackers decompiling my app as well as detect malicious uses?

我目前正在开发一个 android 应用程序,它使用 API 秘密和访问令牌通过 TLS 访问数据。

我正在考虑通过 TLS 从 Firebase 之类的东西发送它,而不是以明文形式将秘密存储在应用程序本地。我会将其加密发送,并使用一种相当模糊的解密方法。然后 API 秘密将用于向 API.

发出请求

是否应该考虑保护密钥?我担心的是恶意实体可能会反编译应用程序并插入他们自己的代码以找出我们隐藏 API 密钥的方法。

我不确定现在有人怎么能算出密钥。我假设他们会反编译代码并在解密后重定向 API 秘密。

最终,无论如何,我知道它可能被黑客入侵,有人可能会发现 API 秘密。然后我如何检测到有人拥有 API 秘密?他们不能伤害其他用户,除非他们拥有访问令牌,这是另一回事,但是是否有任何众所周知的检测攻击的方法?恶意实体可能产生的唯一影响是向 API 假装我们的服务器发送许多请求,这会增加我们的账单,但这仍然应该受到保护。我可以轮换我的秘密,但如果他们已经有找到它的方法,那么这对我来说没什么用。

总结一下: 什么被认为是最佳实践? API 秘密是否应该保留在我们从 Firebase Functions 发出请求的服务器中?如何检测攻击,或者这取决于 API 到 API?如果检测到攻击,我是否必须强制用户更新到新版本以发出请求并在新版本中以新方式隐藏数据?

我已经对此进行了很多思考,但我仍然有一些问题,我自己也没有找到答案,也没有在网上找到答案。谢谢。

在应用程序中存储 API 密钥是有问题的。您可以混淆它或将其隐藏在计算中,但如果这个秘密足够有价值,就会有人提取它。

您正在考虑从服务器发送您的密钥。这样可以将密钥排除在应用程序包本身之外。您必须保护该通信,因此 TLS 是必须的,您应该更进一步 pin the connection 避免中间人攻击。

我不会发送密钥本身,而是发送一个由您的 API 密钥签名的限时令牌。随着时间的推移,您需要发送不同的令牌,但 API 密钥永远不会直接暴露在应用程序上,您可以更改签名密钥而无需应用程序现场升级。如果令牌被盗,至少它只能在有限的时间内有效。

您仍然需要确保您不会将令牌发送到被篡改的应用程序,甚至是对您的协议进行逆向工程的机器人。您需要验证安装的应用程序 package/code 并检查安全的 运行 时间环境(不是 运行 在调试器中,没有像 frida 或 xposed 等框架)。您可以将篡改检测添加到您的应用程序,但由于您已经向您的应用程序发送令牌,我认为这是一种更好的方法来设置一个挑战-响应协议,该协议将以加密方式证明该应用程序。这样你而不是应用程序做出实际的真实性决定。

有关用户和应用真实性的更多背景信息,请查看由 3 部分组成的博客 post,从 Mobile API Security Techniques, or if you prefer video, check out A Tour of Mobile API Underprotection. You can also look at approov.io 开始,了解质询-响应证明和 JWT 令牌的商业实施。