【发布时间】:2019-10-09 05:31:24
【问题描述】:
我创建了 android 应用程序,它运行良好。 问题是,当我们反编译应用程序时,我们可以看到所有代码,因此黑客可以看到我们的 API URL 和 API 类,因此他们可以克隆应用程序。
所以我的问题是如何保护我的 android 应用程序,以便保护它免受黑客攻击。
【问题讨论】:
标签: android security facebook-android-sdk
我创建了 android 应用程序,它运行良好。 问题是,当我们反编译应用程序时,我们可以看到所有代码,因此黑客可以看到我们的 API URL 和 API 类,因此他们可以克隆应用程序。
所以我的问题是如何保护我的 android 应用程序,以便保护它免受黑客攻击。
【问题讨论】:
标签: android security facebook-android-sdk
我创建了 android 应用程序,它运行良好。问题是当我们反编译应用程序时,我们可以看到所有代码,因此黑客可以看到我们的 API URL 和 API 类,因此他们可以克隆应用程序。
无论您使用什么工具来混淆甚至加密代码,您的 API url 在某些时候都需要以明文形式显示,也就是当您执行 API 请求时,因此它很容易被攻击者获取。因此,如果攻击者无法通过静态二进制分析提取它,它将在运行时使用检测框架进行提取,例如Frida:
将您自己的脚本注入黑盒进程。挂钩任何功能、监视加密 API 或跟踪私有应用程序代码,无需源代码。编辑,点击保存,立即查看结果。所有这些都无需编译步骤或程序重新启动。
因此,基本上,攻击者需要在代码中找到您执行 API 请求的位置,将 Frida 挂在上面,然后提取 URL 或随它传递的任何秘密,以在 API 服务器中识别/授权您的移动应用.
攻击者可以采取的另一种方法是在他控制的移动设备中执行中间人攻击,并拦截向 API 服务器发出的请求:
图片来源于文章:Steal that API key with a Man in the Middle Attack
正如您在上面的示例中看到的,截获的 API 请求显示了 API 服务器 url 和正在使用的 API 密钥。
所以我的问题是如何保护我的 android 应用程序,以便保护它免受黑客攻击。
在添加安全性时,无论是针对软件还是针对物质事物,始终与层有关,例如中世纪的城堡,它们不仅具有一层防御,而且具有多层防御。因此,您应该将相同的原则应用于您的移动应用程序。
我将列出一些你应该做的最起码的事情,但不是一个详尽的清单。
本机开发工具包 (NDK) 是一组工具,可让您在 Android 中使用 C 和 C++ 代码,并提供可用于管理本机活动和访问物理设备组件(例如传感器和触摸输入)的平台库.
在 this demo app 中,我展示了如何使用原生 C 代码 to hide the API key 来轻松通过静态二进制分析进行逆向工程,但正如您已经看到的那样,您可以在运行时通过中间人攻击来抓住它。
#include <jni.h>
#include <string>
#include "api_key.h"
extern "C" JNIEXPORT jstring JNICALL
Java_com_criticalblue_currencyconverterdemo_MainActivity_stringFromJNI(
JNIEnv *env,
jobject /* this */) {
// To add the API_KEY to the mobile app when is compiled you need to:
// * copy `api_key.h.example` to `api_key.h`
// * edit the file and replace this text `place-the-api-key-here` with your desired API_KEY
std::string JNI_API_KEY = API_KEY_H;
return env->NewStringUTF(JNI_API_KEY.c_str());
}
如果您想详细了解如何在您的移动应用中实现它,请访问 Github 存储库。
您应该始终混淆您的代码。如果您买不起最先进的解决方案,那么至少使用内置的 ProGuard 解决方案。这增加了浏览代码所需的时间和技能。
您可以使用加密来隐藏敏感代码和数据,快速的 Google 搜索将产生大量资源和技术。
对于用户数据加密,您可以在Android docs开始了解更多信息:
加密是使用对称加密密钥对 Android 设备上的所有用户数据进行编码的过程。一旦设备被加密,所有用户创建的数据在将其提交到磁盘之前都会自动加密,并且所有读取都会在将数据返回到调用进程之前自动解密数据。加密确保即使未经授权的一方试图访问数据,他们也无法读取数据。
您可以阅读Android docs 中的一些示例:
本文档描述了使用 Android 加密工具的正确方法,并包含了一些使用示例。如果您的应用需要更高的密钥安全性,请使用 Android Keystore 系统。
但请记住,使用 Frida 将允许攻击者挂钩返回未加密数据的代码并提取它,但也需要更多的技巧和时间来实现这一点。
这个概念引入了一种新的方式来保护您的移动应用。
传统方法主要集中在客户端,但首先您要保护的数据位于 API 服务器中,您希望在这里有一种机制让您知道什么 发出的请求确实是您的正版移动应用,与您上传到 Google Play 商店的相同。
在深入探讨移动应用认证的角色之前,我想先澄清一个关于 what 与 谁 执行 API 请求的误解,我会引用this article我写道:
what 是向 API 服务器发出请求的事物。它真的是您的移动应用程序的真实实例,还是机器人、自动脚本或攻击者使用 Postman 之类的工具手动绕过您的 API 服务器?
谁是移动应用的用户,我们可以通过多种方式进行身份验证、授权和识别,例如使用 OpenID Connect 或 OAUTH2 流。
在我写的另一篇文章的this section 中描述了移动应用证明角色,我在其中引用了以下文字:
移动应用证明服务的作用是对发送请求的内容进行身份验证,因此只响应来自真正的移动应用实例的请求并拒绝来自未经授权的来源的所有其他请求。
为了了解向 API 服务器发送请求的内容,移动应用证明服务将在运行时以高可信度识别您的移动应用存在、未被篡改/重新打包、未运行在有根设备中,尚未被仪器框架(Frida、xPosed、Cydia 等)挂钩,也不是中间人攻击 (MitM) 的对象。这是通过在后台运行 SDK 来实现的,该 SDK 将与在云中运行的服务进行通信,以证明移动应用程序和运行它的设备的完整性。
成功证明移动应用程序的完整性后,将颁发一个短期 JWT 令牌,并使用只有 API 服务器和云中的移动应用程序证明服务知道的秘密进行签名。在证明失败的情况下,JWT 令牌使用不正确的密钥进行签名。由于移动应用程序不知道移动应用程序证明服务使用的秘密,因此即使应用程序已被篡改、在根设备中运行或通过连接进行通信,也无法在运行时对其进行逆向工程这是 MitM 攻击的目标。
移动应用必须在每个 API 请求的标头中发送 JWT 令牌。这允许 API 服务器仅在可以验证 JWT 令牌已使用共享密钥签名并且尚未过期时才提供请求。所有其他请求将被拒绝。换句话说,有效的 JWT 令牌会告诉 API 服务器发出请求的是上传到 Google 或 Apple 商店的真正移动应用程序,而无效或丢失的 JWT 令牌意味着发出请求的东西未被授权这样做,因为它可能是机器人、重新打包的应用程序或进行中间人攻击的攻击者。
因此,如果 JWT 令牌具有有效的签名并过期,那么这种方法将使您的 API 服务器非常有信心地相信请求确实来自您上传到 Google Play 商店的同一个移动应用程序时间,并将所有其他请求作为不可信的请求丢弃。
我忍不住向你推荐 OWASP 基金会的优秀作品,因为没有经过The Mobile Security Testing Guide 的移动安全解决方案是不完整的:
移动安全测试指南 (MSTG) 是一本用于移动应用安全开发、测试和逆向工程的综合手册。
【讨论】:
您可以使用DexGuard。保护 Android 应用程序和 SDK 免受逆向工程和黑客攻击。DexGuard 提供广泛的自定义选项,使您能够根据您的安全和性能要求调整应用的保护。DexGuard 可防止攻击者深入了解您的源代码并对其进行修改或从中提取有价值的信息.
ProGuard 是 Java 字节码的通用优化器。 DexGuard 是一个 用于保护 Android 应用程序的专用工具。
【讨论】:
我找到了一个网站JavaDecompiler 可以帮助您反编译应用程序。我研究的结果是没有办法提供 100% 的代码安全性。所以我们可以做的是在前端和后端都设置条件。
我曾尝试过 dexguard,但它对我来说很昂贵,而且 proguard 对我来说效果不佳。
【讨论】:
您可以在创建签名 apk 时使用 Android Studio 默认提供的 proguard,您可以参考下面的文档
链接:https://docs.google.com/document/d/1UgEZtKRoAIIXtPLKKHIds33txgU7hH33-3xsoBR4lWY/edit?usp=sharing
【讨论】:
除了使用代码混淆之外,您无能为力。我建议使用 NDK 层来存储应用程序机密,因为 C++ 库不容易被反编译。为此,您可以使用 https://github.com/nomtek/android-client-secrets 库。
【讨论】:
您可以使用 ProGuard 工具来保护您的代码。它使用简短的无意义名称重命名了剩余的类、字段和方法。
【讨论】:
API 端点将始终对最终用户开放。但是,如果您在 api 服务器中使用 https 和 SSL,则数据将像大多数应用程序一样被加密。至于 API 端点,你什么都做不了
【讨论】: