Jay*_*Nai 5 security android facebook-android-sdk
我创建了android应用程序,并且运行良好。问题是,当我们反编译应用程序时,我们可以看到所有代码,因此黑客可以看到我们的API URL和API类,以便他们可以克隆应用程序。
所以我的问题是,如何保护我的android应用程序,以保护其免受黑客攻击。
我创建了 android 应用程序,它运行良好。问题是当我们反编译应用程序时,我们可以看到所有代码,因此黑客可以看到我们的 API URL 和 API 类,以便他们可以克隆应用程序。
无论您使用什么工具来混淆甚至加密代码,您的 API url 在某个时候都需要是明文,也就是在您执行 API 请求时,因此它会被攻击者抢走。因此,如果攻击者无法使用静态二进制分析提取它,它将在运行时使用检测框架(如Frida)进行提取:
将您自己的脚本注入黑盒进程。挂钩任何函数,监视加密 API 或跟踪私有应用程序代码,无需源代码。编辑,点击保存,并立即查看结果。无需编译步骤或程序重新启动。
因此,基本上攻击者需要在代码中找到您执行 API 请求的位置,将 Frida 挂在它上面,然后提取 URL 或随它传递的任何秘密,以在 API 服务器中识别/授权您的移动应用程序。
攻击者可以采取的另一种方法是在他控制的移动设备中执行中间人攻击,并拦截向 API 服务器发出的请求:
图片来自文章:使用中间人攻击窃取 API 密钥
正如您在上面的示例中所看到的,拦截的 API 请求显示了 API 服务器 url 和正在使用的 API 密钥。
所以我的问题是如何保护我的 android 应用程序,以便我可以保护它免受黑客攻击。
在添加安全性时,无论是软件还是物质,总是与层有关,例如中世纪的城堡,它们不是只有一层防御,而是有多层。因此,您应该将相同的原则应用于您的移动应用程序。
我将列出一些你应该做的最少的事情,但不会列出它们的详尽清单。
本机开发工具包 (NDK) 是一组工具,可让您在 Android 中使用 C 和 C++ 代码,并提供可用于管理本机活动和访问物理设备组件(例如传感器和触摸输入)的平台库。
在这个演示应用程序中,我展示了如何使用原生 C 代码来隐藏 API 密钥,以免被静态二进制分析轻松逆向工程,但正如您已经看到的,您在运行时通过中间人攻击来获取它。
#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());
}
Run Code Online (Sandbox Code Playgroud)
如果您想详细了解如何在您的移动应用程序中实现它,请访问 Github 存储库。
你应该总是混淆你的代码。如果您负担不起最先进的解决方案,那么至少使用内置的 ProGuard 解决方案。这增加了浏览代码所需的时间和技能。
您可以使用加密来隐藏敏感代码和数据,快速的谷歌搜索会产生大量资源和技术。
对于用户数据加密,您可以在Android 文档中开始了解更多相关信息:
加密是使用对称加密密钥对 Android 设备上的所有用户数据进行编码的过程。设备加密后,所有用户创建的数据在提交到磁盘之前都会自动加密,所有读取都会在将数据返回到调用进程之前自动解密数据。加密可确保即使未经授权的一方试图访问数据,他们也无法读取数据。
你可以在Android 文档中阅读一些这样做的例子:
本文档描述了使用 Android 加密工具的正确方法,并包含了一些使用示例。如果您的应用需要更高的密钥安全性,请使用 Android Keystore 系统。
但请记住,使用 Frida 将允许攻击者钩入返回未加密数据的代码并提取它,但也需要更多的技巧和时间来实现这一点。
这个概念引入了一种处理移动应用程序安全的新方法。
传统的方法重点多在客户端,但在第一个地方,你要保护的数据是在API服务器,它在这里,你想有一个机制,它可以让你知道什么是发出请求是真的是你真正的移动应用程序,与您上传到 Google Play 商店的应用程序相同。
在深入探讨移动应用认证的角色之前,我想首先澄清一个关于 API 请求是什么和谁在做的误解,我将引用我写的这篇文章:
向 API 服务器发出请求的内容是什么。它真的是您的移动应用程序的真实实例,还是机器人、自动化脚本或攻击者使用 Postman 之类的工具手动浏览您的 API 服务器?
在谁是移动应用,我们可以验证,授权和以多种方式确定,比如使用OpenID登录连接或流的oauth2的用户。
移动应用证明角色在我写的另一篇文章的这一部分中有描述,我引用了以下文字:
移动应用证明服务的作用是验证发送请求的内容,从而仅响应来自真正移动应用实例的请求,并拒绝来自未经授权来源的所有其他请求。
为了了解向 API 服务器发送请求的内容,移动应用证明服务在运行时将高度确定您的移动应用存在、未被篡改/重新打包、未在根目录中运行设备,尚未被检测框架(Frida、xPosed、Cydia 等)连接,也不是中间人攻击 (MitM) 的对象。这是通过在后台运行 SDK 来实现的,该 SDK 将与在云中运行的服务进行通信,以证明其运行的移动应用程序和设备的完整性。
成功证明移动应用程序的完整性后,将发布一个短时间存在的 JWT 令牌,并使用只有 API 服务器和云中的移动应用程序证明服务知道的秘密进行签名。在证明失败的情况下,JWT 令牌使用不正确的秘密进行签名。由于移动应用证明服务使用的秘密不被移动应用知道,因此即使应用被篡改、在有根设备中运行或通过连接进行通信,也无法在运行时对其进行逆向工程这就是中间人攻击的目标。
移动应用程序必须在每个 API 请求的标头中发送 JWT 令牌。这允许 API 服务器仅在可以验证 JWT 令牌是否已使用共享密钥签名且未过期时才提供请求。所有其他请求将被拒绝。换句话说,一个有效的 JWT 令牌告诉 API 服务器发出请求的是上传到 Google 或 Apple 商店的正版移动应用程序,而无效或丢失的 JWT 令牌意味着发出请求的内容没有被授权这样做,因为它可能是机器人、重新打包的应用程序或进行中间人攻击的攻击者。
因此,如果 JWT 令牌具有有效的签名和过期时间,则这种方法将使您的 API 服务器以非常高的置信度相信请求确实来自您上传到 Google Play 商店的同一个移动应用程序,并且将所有其他请求作为不可信的请求丢弃。
我无法抗拒向您推荐 OWASP 基金会的出色工作,因为不阅读移动安全测试指南,移动安全解决方案是不完整的:
移动安全测试指南 (MSTG) 是移动应用安全开发、测试和逆向工程的综合手册。
您可以使用DexGuard. 保护 Android 应用程序和 SDK 免遭逆向工程和黑客攻击。DexGuard 提供广泛的自定义选项,使您能够根据您的安全和性能要求调整应用的保护。DexGuard 可防止攻击者深入了解您的源代码并修改它或从中提取有价值的信息.
ProGuard 是 Java 字节码的通用优化器。DexGuard 是用于保护 Android 应用程序的专用工具。