保护您的 API KEY 免遭逆向工程 Android

Bln*_*pwr 7 android proguard

我对 ProGuard 有点失望。我正在使用 Gradle 来隐藏我的 Google MAP API KEYS。我还在此处阅读了此问题,在 Android Studio 中使用 Gradle 管理 Google Maps API 密钥 并执行相同操作。如果您遵循此问题中已接受的答案,您的 api 密钥将不会被 ProGuard 混淆。问题是为什么?有两个很好的答案。一种带有 ManifestPlaceHolder,一种带有 using@string

尽管如此,如果我反编译我的应用程序,仍然可以看到我的天气 api 密钥。我正在使用private String myweatherapikey = BuildConfig.MY_API_WEATHER_KEY;并且令人惊讶(以一种糟糕的方式)ProGuard 如何不混淆这一点,即使在使用 Gradle 时也是如此。当您进行逆向工程时,它看起来像private String myweatherapikey ="MY KEY IN PLAIN TEXT";

几天以来,我一直试图混淆我的密钥,但没有任何效果,即使使用 Gradle。你如何隐藏你的钥匙?当你反编译我的应用程序时,我所有的密钥都是公开的,这让我很恼火。

第二个问题:我认为隐藏你的谷歌地图 api 密钥是不可能的。有 2 个键,一个用于发布版本,一个用于调试版本。它们都存储在 src/debug 和 src/release 中。你不能隐藏这一点,对吧?

Exa*_*a37 8

混淆

你的 api 密钥不会被 ProGuard 混淆

如果 Proguard 或任何其他工具混淆了 API 密钥,那么它也需要在运行时进行反混淆,否则您无法使用它。

无论您是否有混淆机制甚至加密机制,攻击者只需要在运行时将检测框架(如 Frida)挂钩到在去混淆或解密后返回 API 的代码即可。

弗里达

将您自己的脚本注入黑盒进程。挂钩任何函数、监视加密 API 或跟踪私有应用程序代码,无需源代码。编辑,点击保存,然后立即看到结果。全部无需编译步骤或程序重新启动。

攻击者的另一种方法是在他控制或能够入侵的设备中执行 MitM 攻击,并拦截移动应用程序和后端之间的所有请求,以便从标头中提取 API 密钥,您可以阅读我的文章通过中间人攻击窃取 API 密钥,了解如何做到这一点:

因此,在本文中,您将了解如何设置和运行 MitM 攻击,以拦截您控制下的移动设备中的 https 流量,以便窃取 API 密钥。最后,您将在较高层面上了解如何缓解 MitM 攻击。

是的,这是公开的

几天来我一直在尝试混淆我的密钥,但没有任何效果,即使使用 Gradle 也是如此。你如何隐藏你的钥匙?当你反编译我的应用程序时,我的所有密钥都是公开的,这真的让我很恼火。

从您将移动应用程序发布到 Google、Apple 商店或任何其他商店的那一刻起,二进制文件就可以下载并进行逆向工程,因此其中的任何内容都必须被视为属于公共领域,无论是秘密还是代码。

隐藏 API 密钥并对它们进行逆向工程的技术

我最喜欢的对移动应用程序二进制文件进行逆向工程的工具是MobSF

移动安全框架 (MobSF) 是一种自动化、一体式移动应用程序 (Android/iOS/Windows) 笔测试、恶意软件分析和安全评估框架,能够执行静态和动态分析。

您可以阅读我的文章如何使用静态二进制分析从移动应用程序中提取 API 密钥,了解这是如何完成的,同时了解用于尝试隐藏 API 密钥的几种技术,并了解如何轻松绕过它们:

在本文中,我们将使用Android Hide Secrets研究存储库,它是一个虚拟移动应用程序,使用多种不同的技术隐藏 API 密钥。

现在是时候寻找一种更先进的技术来隐藏 API 密钥,这种方式很难从 APK 进行逆向工程,为此,我们将通过利用 JNI 使用本机 C++ 代码来存储 API 密钥在底层使用 NDK 的接口。

谷歌地图 API 密钥

第二个问题:我认为隐藏你的谷歌地图 API 密钥是不可能的。有 2 个密钥,一个用于发布版本,一个用于调试版本。它们都存储在 src/debug 和 src/release 中。你无法隐藏这一点,对吧?

如果您已阅读我上面发布的所有链接,那么现在您可能已经意识到,在移动应用程序的二进制文件中隐藏任何秘密确实是一项不可能完成的任务。

最重要的是,如果它在二进制文件中,则可以通过静态分析或在运行时提取。

我不太熟悉移动应用程序中的 Google 地图使用情况,因此我不知道是否可以将其调用移至后端,因为这是在移动应用程序中使用第三方 API 时必须完成的操作移动应用程序,否则 API 密钥很容易被提取和滥用,如果您根据它进行计费或费率限制,那么当攻击者获得您的 API 密钥时,您可能会遇到麻烦。

第三方API

目前,您使用第三方 API 会使您的移动应用程序处于以下位置:

移动应用程序中第三方 API 的错误使用

但您的移动应用程序优先应处于以下位置:

移动应用程序中第三方 API 的正确使用

虽然在图形中我提到了反向代理,但它可能是您的移动应用程序的后端。

注意:这些图形属于我目前正在撰写的一篇关于使用反向代理访问第三方 API 的文章。

当将对第三方 API 的访问委托给我们控制的反向代理或后端时,保护 API 密钥的安全性要容易得多,这种方法的直接优势是第三方服务的 API 密钥不再存在于第三方 API 中。公共领域,又名移动应用程序的二进制文件。

因此,从图形来看,我们只剩下一个 API 密钥需要保护,即用于访问反向代理或后端的密钥,您可以在其中采取尽可能多的安全措施来防止未经授权的访问。

可能的解决方案

你如何隐藏你的钥匙?

在您的移动应用程序中根本不隐藏任何密钥并不是更好,因为这将是理想的解决方案。所以上面的图形看起来更像是:

移动应用程序中没有 API 密钥

为了不需要在移动应用程序中传递任何秘密,您需要诉诸移动应用程序证明概念,从本文部分我将提取相关部分,解释它的作用:

在深入研究移动应用程序证明服务的作用之前,我们首先需要了解访问 API 服务器的内容访问者之间的区别。本文对此进行了更详细的讨论,我们可以在其中阅读:

向 API 服务器发出请求的是什么。它真的是您的移动应用程序的真实实例,还是机器人、自动化脚本或攻击者使用 Postman 等工具手动探查您的 API 服务器?

我们可以通过多种方式(例如使用 OpenID Connect 或 OAUTH2 流)对移动应用程序的用户进行身份验证、授权和识别

移动应用程序证明服务的作用是对发送请求的内容进行身份验证,从而仅响应来自真实移动应用程序实例的请求,并拒绝来自未经授权的来源的所有其他请求。

为了了解向 API 服务器发送请求的内容,移动应用程序证明服务将在运行时高度确信您的移动应用程序存在、未被篡改/重新打包、未在 root 中运行。设备,尚未被仪表框架(Frida、xPosed、Cydia 等)挂钩,并且不是中间人攻击 (MitM)的对象。这是通过在后台运行 SDK 来实现的,该 SDK 将与云中运行的服务进行通信,以证明移动应用程序及其运行设备的完整性。

成功证明移动应用程序完整性后,将颁发一个短期JWT 令牌,并使用只有 API 服务器和云中的移动应用程序证明服务知道的秘密进行签名。如果证明失败,JWT 令牌将使用不正确的密钥进行签名。由于移动应用程序证明服务使用的秘密对于移动应用程序来说是未知的,因此即使应用程序已被篡改、在已取得 root 权限的设备中运行或通过连接进行通信,也无法在运行时对其进行逆向工程这是中间人攻击的目标。

移动应用程序必须在每个 API 请求的标头中发送 JWT 令牌。这允许 API 服务器仅在可以验证 JWT 令牌是使用共享密钥签名且尚未过期时才处理请求。所有其他请求都将被拒绝。换句话说,有效的 JWT 令牌告诉 API 服务器发出请求是上传到 Google 或 Apple 商店的正版移动应用程序,而无效或丢失的 JWT 令牌意味着发出请求的内容未经授权。 ,因为它可能是机器人、重新打包的应用程序或进行 MitM 攻击的攻击者。

使用移动应用程序认证服务的一大好处是其主动且积极的身份验证模型,不会产生误报,因此不会阻止合法用户,同时将坏人拒之门外。

移动应用程序证明使您的移动应用程序能够在其代码中嵌入秘密,而现在它只需将从证明接收到的 JWT 令牌传递给反向代理或后端。现在,反向代理或后端可以验证 JWT 令牌,并且在成功验证后,他们可以非常有信心地满足请求,这些请求源自他们期望的移动应用程序的真实实例,并且具有不暴露JWT 令牌的额外好处用于访问您的第三方服务的 API 密钥。

更加努力

我忍不住推荐OWASP - 移动安全测试指南中所做的出色工作:

移动安全测试指南 (MSTG) 是移动应用安全开发、测试和逆向工程的综合手册。