android - 在 Android (flutter) 应用程序中安全地保存 API key

标签 android firebase api security flutter

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

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

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

  • 这怎么可能呢?服务器将把 api key 发送到应用程序。如果黑客找到了这个 url,他们可以打开它并获取 key 。如果我使用 key 访问 URL,那么我将进入一个永无止境的 key 循环。我该怎么做?
  • 有人说我可以加密我的 key ,然后在收到应用程序后将它们解密。但是人们不能反编译我的解密函数并找出我的 key 吗?

  • 我还被告知 Firebase 远程配置将成为存储我的 key 的安全方法。但是还有另一个问题
  • 这种方法有多安全?
  • 如果我使用 google services json 文件来标识我的项目,那么人们不能从删除配置部分获取我的 key 吗?因为我在我的控制台上看不到删除配置的任何设置,以便说明谁可以访问这个,谁不能。如何在 Firebase 上安全地存储我的 api key ?
  • 黑客不能反编译 apk 并更改代码并从我的 firebase 帐户中提取数据吗?因为谷歌服务json在那里。如果他们打印提取的数据,他们可以访问所有内容吗?

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

    最佳答案

    提取 API key 有多难?

    My API Key will still be in that app when someone decompiles the apk file. Sure it might take more time, but how much more is it? For example 20 minutes? I feel like the bottom line is that they can use this key if they put some time and effort. Am I getting this wrong?



    你说For example 20 minutes? ...好吧,这取决于您是否已经在计算机中安装了这些工具,但是如果您至少安装了 Docker,则可以
    利用一些惊人的开源工具,这些工具将使您在不到 20 分钟,也许大约 5 分钟的时间内提取 API key 变得微不足道,请继续阅读以了解如何做到这一点。

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

    你可以关注我关于How to Extract an API Key from a Mobile App with Static Binary Analysis的文章在那里你将学习如何在五分钟内完成它,而无需任何事先的黑客知识,我引用的地方:

    I will now show you a quick demo on how you can reverse engineer an APK with MobSF in order to extract the API Key. We will use the MobSF docker image, but you are free to install it in your computer if you wish, just follow their instructions to do it so.

    To run the docker image just copy the docker command from the following gist:

    #!/bin/bash
    
    docker run -it --name mobsf -p 8000:8000 opensecurity/mobile-security-framework-mobsf
    


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

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

    By now the only API key we have not been able to find is the JNI_API_KEY from the C++ native code, and that is not so easy to do because the C++ code is compiled into a .so file that is in HEX format and doesn’t contain any reference to the JNI_API_KEY, thus making it hard to link the strings with what they belong to.



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

    使用中间人攻击提取 API key

    关注我的文章Steal that API Key with a Man in the Middle Attack要将其提取到您可以控制的设备中:

    In order to help to demonstrate how to steal an API key, I have built and released in Github the Currency Converter Demo app for Android, which uses the same JNI/NDK technique we used in the earlier Android Hide Secrets app to hide the API key.

    So, in this article you will learn how to setup and run a MitM attack to intercept https traffic in a mobile device under your control, so that you can steal the API key. Finally, you will see at a high level how MitM attacks can be mitigated.



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

    In a previous article we saw how to protect the https communication channel between a mobile app and an API server with certificate pinning, and as promised at the end of that article we will now see how to bypass certificate pinning.

    To demonstrate how to bypass certificate pinning we will use the same Currency Converter Demo mobile app that was used in the previous article.

    In this article you will learn how to repackage a mobile app in order to make it trust custom ssl certificates. This will allow us to bypass certificate pinning.



    使用检测框架提取

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

    Inject your own scripts into black box processes. Hook any function, spy on crypto APIs or trace private application code, no source code needed. Edit, hit save, and instantly see the results. All without compilation steps or program restarts.



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

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

    Someone said that I can encrypt my keys and then decrypt them in the app once it's received.



    所以你可以使用 Android Hardware-backed Keystore :

    The availability of a trusted execution environment in a system on a chip (SoC) offers an opportunity for Android devices to provide hardware-backed, strong security services to the Android OS, to platform services, and even to third-party apps.



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

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

    But can't people decompile my decryption function and figure out my key?



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

    I was also told that Firebase Remote Config is going to be a safe method for storing my keys.



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

    哦,但您可能会说 Firebase 和/或您的手机受 SafetyNET 保护,那么我需要提醒您,SafetyNet 会检查运行移动应用的设备的完整性,而不是移动应用本身的完整性,按照 Google own statement :

    The goal of this API is to provide you with confidence about the integrity of a device running your app. You can then obtain additional signals using the standard Android APIs. You should use the SafetyNet Attestation API as an additional in-depth defense signal as part of an anti-abuse system, not as the sole anti-abuse signal for your app.



    另外我建议你阅读 this answer我给出了 Android 相当于 ios devicecheck 的问题?以便了解开发人员在其移动应用程序中实现 Safety Net 时需要注意的事项。

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

    代理或后端服务器

    Now the other answer that I've seen on different websites was that I can store my keys on a server and then communicate that through my app.

    How is that even possible? A server is going to send the api key to the app. If the hacker finds this url they can just open it and get the key. If I use a key to access the URL then i'm entering a never ending loop of keys. How would I do this?



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

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

    可能更好的解决方案

    So what exactly should I do to safely use api keys for my third party applications? And some of these api keys are very valuable and some of them just get information from other servers. I just want to know the safest method to store these keys.



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

    你想走得更远吗?

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

    对于移动应用程序

    OWASP Mobile Security Project - Top 10 risks

    The OWASP Mobile Security Project is a centralized resource intended to give developers and security teams the resources they need to build and maintain secure mobile applications. Through the project, our goal is to classify mobile security risks and provide developmental controls to reduce their impact or likelihood of exploitation.



    OWASP - Mobile Security Testing Guide :

    The Mobile Security Testing Guide (MSTG) is a comprehensive manual for mobile app security development, testing and reverse engineering.



    用于APIS

    OWASP API Security Top 10

    The OWASP API Security Project seeks to provide value to software developers and security assessors by underscoring the potential risks in insecure APIs, and illustrating how these risks may be mitigated. In order to facilitate this goal, the OWASP API Security Project will create and maintain a Top 10 API Security Risks document, as well as a documentation portal for best practices when creating or assessing APIs.

    关于android - 在 Android (flutter) 应用程序中安全地保存 API key ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61894868/

    相关文章:

    android - 如何在android中使用put方法向HTTPBody添加数据

    java - Java 是 Android 编程的唯一方法有什么特殊原因吗?

    reactjs - 在 Firebase : New deployment not showing (old deployment cached in browser) 上 react 应用

    python - duckduckgo API 不返回结果

    php - 在 PHP 中从字符串创建唯一整数

    android - 在 android gradle 中导入 itext-7

    android - 当我为警告对话框中的编辑文本执行 getText() 时获取空指针 (Android)

    javascript - Firebase 安全规则来自特定 Web url 的存储

    android - 使用 firebase 和 dialog-flow 解决重复类

    javascript - 如何使谷歌饼图api背景透明