在 Android (flutter) 应用程序中安全地保存 API 密钥

SOM*_*GUY 5 security api android firebase flutter

我知道这个问题已经被问过很多次了。我已经阅读了所有这些。我已经在谷歌中搜索过这个问题,但我仍然有一些我无法找到答案的问题。

目前我正在我的应用程序中存储 API 密钥。是的,这是一种不好的做法。现在据我所知,我可以使用 ProGaurd 或 DexGaurd 进行混淆。我还可以使用 Keystore 来安全地存储我的 api 密钥。现在对于这一部分,我的问题是: - 混淆会更改变量和类的名称。当有人反编译 apk 文件时,我的 API 密钥仍将在该应用程序中。当然可能需要更多时间,但又需要多少时间呢?例如20分钟?我觉得最重要的是,如果他们投入一些时间和精力,他们可以使用此密钥。我弄错了吗?

现在我在不同网站上看到的另一个答案是我可以将我的密钥存储在服务器上,然后通过我的应用程序进行通信。

  • 这怎么可能呢?服务器将把 api 密钥发送到应用程序。如果黑客找到了这个 url,他们可以打开它并获取密钥。如果我使用密钥访问 URL,那么我将进入一个永无止境的密钥循环。我该怎么做?

  • 有人说我可以加密我的密钥,然后在收到应用程序后将它们解密。但是人们不能反编译我的解密函数并找出我的密钥吗?

我还被告知 Firebase 远程配置将成为存储我的密钥的安全方法。但是还有另一个问题

  • 这种方法有多安全?
  • 如果我使用 google services json 文件来标识我的项目,那么人们不能从删除配置部分获取我的密钥吗?因为我在我的控制台上看不到任何删除配置的设置,以便说明谁可以访问这个,谁不能。如何在 Firebase 上安全地存储我的 api 密钥?

  • 黑客不能反编译 apk 并更改代码并从我的 firebase 帐户中提取数据吗?因为谷歌服务json在那里。如果他们打印提取的数据,他们可以访问所有内容吗?

那么我到底应该怎么做才能安全地将 api 密钥用于我的第三方应用程序?其中一些 api 密钥非常有价值,其中一些只是从其他服务器获取信息。我只想知道存储这些密钥的最安全方法。

Exa*_*a37 18

提取 API 密钥有多难?

当有人反编译 apk 文件时,我的 API 密钥仍将在该应用程序中。当然可能需要更多时间,但又需要多少时间呢?例如20分钟?我觉得最重要的是,如果他们投入一些时间和精力,他们可以使用此密钥。我弄错了吗?

你说For example 20 minutes?......好吧,这取决于你是否已经在你的计算机上安装了这些工具,但是如果你至少安装了 Docker,你可以利用一些惊人的开源工具,这将使你轻松提取 API Key远少于 20 分钟,也许大约 5 分钟,请继续阅读以了解如何做到这一点。

使用静态二进制分析提取 API 密钥

您可以关注我关于如何使用静态二进制分析从移动应用程序中提取 API 密钥的文章,在那里您将了解如何在五分钟内完成此操作,并且无需任何事先的黑客知识,我引用的内容如下:

我现在将向您展示如何使用 MobSF 对 APK 进行逆向工程以提取 API 密钥的快速演示。我们将使用 MobSF docker 镜像,但如果您愿意,您可以自由地将其安装在您的计算机中,只需按照他们的说明进行操作即可。

要运行 docker 镜像,只需从以下要点复制 docker 命令:

#!/bin/bash

docker run -it --name mobsf -p 8000:8000 opensecurity/mobile-security-framework-mobsf
Run Code Online (Sandbox Code Playgroud)

因此,在 docker 容器启动并运行后,您需要做的就是访问http://localhost:8000并在 Web 界面中上传您的移动应用程序二进制文件,然后等待 MobSF 为您完成所有繁重的工作。

现在,如果您将 API 密钥隐藏在本机 C/C++ 代码中,那么上述方法将不起作用,正如我在同一篇文章中所述:

到目前为止,我们无法找到的唯一 API 密钥是来自 C++ 本机代码的 JNI_API_KEY,这并不容易,因为 C++ 代码被编译成一个 HEX 格式的 .so 文件,并且没有包含对 JNI_API_KEY 的任何引用,因此很难将字符串与其所属的内容链接起来。

但是不要担心您可以使用中间人(MitM)攻击或检测框架来提取 API 密钥。

使用中间人攻击提取 API 密钥

只需按照我的文章使用中间人攻击窃取 API 密钥,即可在您可以控制的设备中提取它:

为了帮助演示如何窃取 API 密钥,我在 Github 中构建并发布了适用于 Android的Currency Converter Demo应用程序,它使用与我们在早期的Android Hide Secrets应用程序中使用的JNI/NDK技术相同的JNI/NDK技术来隐藏 API 密钥.

因此,在本文中,您将学习如何设置和运行中间人攻击来拦截您控制下的移动设备中的 https 流量,以便您可以窃取 API 密钥。最后,您将在高层次上看到如何缓解 MitM 攻击。

哦,但你可能会说你使用证书锁定,因此中间人攻击将不起作用,如果是这样,我邀请你阅读我关于绕过证书锁定的文章:

上一篇文章中,我们看到了如何使用证书锁定保护移动应用程序和 API 服务器之间的 https 通信通道,正如该文章末尾所承诺的那样,我们现在将看到如何绕过证书锁定。

为了演示如何绕过证书锁定,我们将使用与上一篇文章中使用的相同的货币转换器演示移动应用程序。

在本文中,您将学习如何重新打包移动应用程序以使其信任自定义 ssl 证书。这将允许我们绕过证书锁定。

使用检测框架提取

因此,如果上述方法都不适合您,那么您可以使用检测框架,例如使用非常广泛的Frida

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

所以无论你最终做什么,移动应用程序中的秘密总是可以被提取出来的,这取决于攻击者的技能组合以及他愿意投入的时间和精力。

在移动应用程序中存储加密的 API 密钥?

有人说我可以加密我的密钥,然后在收到应用程序后将它们解密。

因此,您可以使用Android 硬件支持的密钥库

片上系统 (SoC) 中可信执行环境的可用性为 Android 设备提供了向 Android 操作系统、平台服务甚至第三方应用程序提供硬件支持的强大安全服务的机会。

在某些时候,需要使用从该密钥库中检索到的秘密来发出 http 请求,此时攻击者需要做的就是在调用函数时挂钩检测框架,该函数返回解密以提取的 API 密钥它什么时候返回。

为了找到解密函数,攻击者需要做的就是反编译你的 APK 并找到它,就像你已经关闭的那样:

但是人们不能反编译我的解密函数并找出我的密钥吗?

用于救援的消防和安全网?

我还被告知 Firebase 远程配置将成为存储我的密钥的安全方法。

再一次,攻击者需要做的就是使用检测框架从他识别为使用 Firebase 配置的任何函数中提取所有需要的东西。

哦,但您可能会说 Firebase 和/或您的手机受 SafetyNET 保护,那么我需要提醒您注意,SafetyNet 会检查运行移动应用的设备的完整性,而不是移动应用本身的完整性,根据谷歌自己的声明

此 API 的目标是让您对运行您的应用程序的设备的完整性充满信心。然后,您可以使用标准 Android API 获取其他信号。您应该将 SafetyNet Attestation API 作为额外的深度防御信号作为反滥用系统的一部分,而不是作为应用程序的唯一反滥用信号。

另外,我建议您阅读我对Android 等效于 ios devicecheck的问题给出的答案以便了解开发人员在其移动应用程序中实施 Safety Net 时需要注意的事项。

因此,尽管 SafetyNet 对 Android 安全生态系统来说是一个非常好的改进,但它并非旨在用作独立防御,也不能保证移动应用程序不会被篡改,因为您想要使用移动应用程序证明概念。

代理或后端服务器

现在我在不同网站上看到的另一个答案是我可以将我的密钥存储在服务器上,然后通过我的应用程序进行通信。

这怎么可能呢?服务器将把 api 密钥发送到应用程序。如果黑客找到了这个 url,他们可以打开它并获取密钥。如果我使用密钥访问 URL,那么我将进入一个永无止境的密钥循环。我该怎么做?

虽然您可能会说这只会将问题从移动应用程序转移到代理或后端服务器,但我不得不说,至少代理或后端服务器是在您的控制之下,而移动应用程序则不是。任何下载它的人都可以随心所欲地使用它,并且您无法直接控制,您只能在 APK 中添加尽可能多的障碍以使其变得困难。

我建议您阅读如何通过哈希比较限制使用 API 密钥的问题的回答更好地理解为什么不应该尝试保护移动应用程序中的 API 密钥,而是将它们移动到后端或代理服务器。

可能更好的解决方案

那么我到底应该怎么做才能安全地将 api 密钥用于我的第三方应用程序?其中一些 api 密钥非常有价值,其中一些只是从其他服务器获取信息。我只想知道存储这些密钥的最安全方法。

我在这里可以给您的最佳建议是阅读如何保护移动应用程序的 API REST问题的回答了解您如何确实可以在移动应用程序中使用 API 密钥,并让您的后端高度确信请求确实来自您的移动应用程序的真实实例。

你想多走一英里吗?

在对安全问题的任何回答中,我总是喜欢参考 OWASP 基金会的出色工作。

对于移动应用程序

OWASP 移动安全项目 - 十大风险

OWASP 移动安全项目是一个集中资源,旨在为开发人员和安全团队提供构建和维护安全移动应用程序所需的资源。通过该项目,我们的目标是对移动安全风险进行分类并提供开发控制以减少其影响或被利用的可能性。

OWASP - 移动安全测试指南

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

用于APIS

OWASP API 安全前 10 名

OWASP API 安全项目旨在通过强调不安全 API 中的潜在风险并说明如何减轻这些风险来为软件开发人员和安全评估人员提供价值。为了实现这一目标,OWASP API 安全项目将创建和维护一个前 10 个 API 安全风险文档,以及创建或评估 API 时最佳实践的文档门户。


San*_*rma 4

如果您认为 API 密钥不应被泄露,那么您不应将其放入应用程序中。您可以使用以下可能的解决方案

  1. 您可以将密钥保存在服务器上,并通过服务器路由所有需要该密钥的请求。因此,只要您的服务器是安全的,那么您的密钥也是安全的。当然,此解决方案会带来性能成本。您可以使用 SSL 固定来验证响应。检查这个
  2. 您可以通过编程方式获取应用程序的签名密钥,并将其发送到每个 API 调用中以验证请求。但黑客可以通过某种方式找出策略。
  3. Google 不建议在远程配置中存储 API 密钥,但您可以在那里保留一个令牌并使用它来验证请求并发送 API 密钥。检查这个
  4. 对于Android应用程序,您可以使用Google的SafetyNet API来验证应用程序的真实性,并且服务器可以在验证SafetyNet响应后为用户生成令牌。该令牌可以进一步用于验证请求。Flutter for SafetyNet API有一个可用的插件。

您可以结合使用上述方法来保证API密钥的安全。为了回答您的问题,Firebase 远程配置使用 SSL 连接来传输数据,它非常安全,但您不应该完全依赖它来保证数据安全。您也无法使用可公开访问的 API 共享 API 密钥。此外,将加密密钥和数据都存储在应用程序内并不能保证其安全。


归档时间:

查看次数:

4509 次

最近记录:

5 年,9 月 前