在Android(颤振)应用中安全保存API密钥

时间:2020-05-19 15:31:52

标签: android firebase api security flutter

我知道这个问题已经问过很多遍了。我都看过了我已经在Google中搜索过此内容,但仍然有我无法找到答案的问题。

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

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

  • 那怎么可能?服务器将向应用程序发送api密钥。如果黑客找到了该URL,则可以将其打开并获取密钥。如果我使用密钥来访问URL,那么我正在输入一个永无休止的密钥循环。我该怎么办?

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

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

  • 这种方法安全多少?
  • 如果我使用的是google services json文件来标识我的项目,那么人们是否只能从remove config部分获取我的密钥?因为我无法在控制台上看到任何关于remove config的设置,以便说出哪些人可以访问此权限,哪些人不能访问。如何将我的api密钥安全地存储在Firebase上?

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

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

2 个答案:

答案 0 :(得分:8)

如何很难提取API密钥?

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

您说For example 20 minutes? ...嗯,这取决于您是否已经在计算机中安装了工具,但是如果您至少已安装了Docker,则可以 利用一些令人惊叹的开放源代码工具,使您在不到20分钟(也许5分钟左右)的时间内提取API密钥变得轻而易举,只需继续阅读以了解如何做即可。

通过静态二进制分析提取API密钥

您可以阅读我关于How to Extract an API Key from a Mobile App with Static Binary Analysis的文章,在其中您将学习如何在五分钟内做到这一点,而这在没有任何黑客技巧的情况下,我引用:

我现在将向您展示一个快速演示,演示如何使用MobSF对APK进行反向工程以提取API密钥。我们将使用MobSF docker映像,但是您可以根据需要随意将其安装在计算机中,只需按照他们的说明进行操作即可。

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

#!/bin/bash

docker run -it --name mobsf -p 8000:8000 opensecurity/mobile-security-framework-mobsf

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

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

现在,我们唯一找不到的API密钥是C ++本机代码中的JNI_API_KEY,这并不是一件容易的事,因为C ++代码被编译成.so文件,格式为HEX,不包含对JNI_API_KEY的任何引用,因此很难将字符串与字符串所属的链接起来。

但是请放心,您可以只使用中间人(MitM)攻击或工具框架来提取API密钥。

通过MitM攻击提取API密钥

只需按照我的文章Steal that API Key with a Man in the Middle Attack将其提取到您可以控制的设备中即可:

为了帮助演示如何窃取API密钥,我在Github中构建并发布了Android版Currency Converter Demo应用,该应用使用了与之前{{ 3}}应用到JNI/NDK

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

哦,但是您可能会说您使用证书固定,因此MitM攻击将不起作用,如果是的话,我邀请您阅读有关Android Hide Secrets的文章:

hide the API key中,我们看到了如何通过证书固定来保护移动应用程序和API服务器之间的https通讯通道,并且如该文章结尾所承诺的,我们现在将看到如何绕过证书固定。

为演示如何绕过证书固定,我们将使用与上一篇文章相同的Byapssing Certificate Pinning移动应用程序。

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

使用检测框架提取

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

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

因此,无论您最终做什么,始终可以提取出移动应用程序中的秘密,这取决于攻击者的技能水平以及他愿意投入的时间和精力。

要存储移动应用中加密的API密钥吗?

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

因此,您可以使用Currency Converter Demo

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

在某个时候,将从该密钥库中检索到的机密用于发出http请求,这时,攻击者所需要做的就是将工具框架挂接到对返回API密钥的函数的调用上返回时解密以提取它。

要找到解密功能,攻击者所需要做的就是对您的APK进行反编译并找到它,就像您已经关闭了一样:

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

救灾的防火墙和安全网?

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

一旦攻击者需要做的就是使用检测框架从他确定为使用Firebase配置的任何功能中提取所有需要的信息。

哦,但是您可能会说Firebase和/或您的移动设备已受到SafetyNET的保护,因此我需要提醒您,SafetyNet检查运行移动应用程序的设备的完整性,而不是移动设备的完整性。应用本身,按照Frida

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

我还建议您阅读Android Hardware-backed Keystore,我提出的问题是与ios devicecheck等效的Android吗?,以便了解开发人员在其移动设备上实施Safety Net时需要了解的内容应用程序。

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

代理或后端服务器

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

那怎么可能?服务器将向应用程序发送api密钥。如果黑客找到了该URL,则可以将其打开并获取密钥。如果我使用密钥来访问URL,那么我正在输入一个永无休止的密钥循环。我该怎么办?

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

我建议您阅读Google own statement这个问题,即如何通过哈希比较来限制API密钥的使用?,以更好地理解为什么您不应该尝试在其中保护API密钥您的移动应用程序,而是将其移动到您的后端或代理服务器。

更好的解决方案

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

在这里,我能给您的最佳建议是this answer,请阅读问题如何保护移动应用程序的API REST?,以了解您实际上如何获得API密钥在移动应用程序中运行,并让您的后端对请求确实来自移动应用程序的真实实例充满信心。

您想参加额外的战斗吗?

在回答安全问题时,我总是喜欢引用OWASP基金会的出色工作。

对于移动应用

my answer

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

my answer

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

对于APIS

OWASP Mobile Security Project - Top 10 risks

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

答案 1 :(得分:2)

如果您认为不应该破坏API密钥,则不要将其放入应用程序中。您可以使用以下可能的解决方案

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

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