如何在 Android 应用程序中保护密钥?

How to secure secret keys in Android App?

我的 Android 应用程序有一个 excel 导出和导入功能,我最近想通过添加写保护密钥来保护它。起初我把密钥硬编码在源代码中,但显然由于逆向工程,这根本不安全。 我读了很多书,我认为我的解决方案现在是安全的,但我不确定。您能否看一下并指出可能的注意事项?

  1. 想要导出 excel 的用户必须使用他们的 Google 帐户登录 Google 登录。
  2. 我的应用请求来自 google 的登录令牌(通过 sha 签名验证)
  3. 登录令牌已发送到我的服务器 (HTTPS POST)
  4. 我的服务器验证该令牌是经 Google 验证的有效令牌。 文档:https://developers.google.com/identity/sign-in/android/backend-auth
  5. 发回 App 帐户信息并excel 将机密导出为 JSON 格式 (HTTPS POST)
  6. App使用密码保护excelsheet并导出。

只能再次导入使用提供的密码导出的 excel sheet。

我还有 PDF 导出功能。 PDF 应由应用程序签名。该过程与以前相同,但使用包含私钥的 pkcs 密钥和 public 密钥作为 base64 字符串。

获得 root 权限的设备如何,攻击者是否可以获取发送的 password/pkcs 密钥?

首先,没有 100% 安全的方法来存储它,即使您将它编译成本机 C 文件。

要隐藏它们,您可以在执行时对其进行加密和解密。要加密您的字符串并向迷路的黑客注入假代码,您可以试试这个 Gradle 插件:https://github.com/christopherney/Enigma

我写了一篇关于它的短文:https://medium.com/@christopherney/protect-android-app-against-reverse-engineering-with-enigma-string-obfuscation-plugin-11687022cbef

还有其他插件,例如https://github.com/StringCare/AndroidLibrary

可能的注意事项

I read a lot and I think my solution is now secure, but I am not sure. Could you maybe have a look and point out possible caveats?

乍一看:

  1. 从私钥离开后端服务器的那一刻起,它就属于 public 域,因此必须将其视为已泄露。
  2. 移动应用程序正在做出重要决定、签署文档并验证其签名,这可以在 run-time 处通过检测框架(如 Frida 和 xPosed)绕过。
  3. 后端服务器只对请求中的用户进行身份验证,而不是发出请求的内容

1。私钥

  1. Send back App account infos and excel export secret as JSON format (HTTPS POST)

The procedure is the same as before, but with a pkcs key containing the private and public key as base64 string.

私钥保持私密的唯一方法是将它安全地存储在它打算使用的地方,我强烈建议在与它相同的地方生成它正在使用,也就是同一台服务器。

私钥 离开后端服务器的那一刻起,它就不再安全存储,现在任何有技能和知识的人都可以使用它来使用过多的用于逆向工程静态二进制文件的开源和付费工具,甚至可以在 run-time 期间内省它们,并更改它们的行为或提取数据,也就是您的 私钥 .

对于静态二进制文件分析,我们有一个开源工具 MobSF,它结合了其他几个开源工具,de-compiles,分析和提取静态二进制文件中的数据。

MobSF

Mobile Security Framework (MobSF) is an automated, all-in-one mobile application (Android/iOS/Windows) pen-testing, malware analysis and security assessment framework capable of performing static and dynamic analysis. MobSF support mobile app binaries (APK, IPA & APPX) along with zipped source code and provides REST APIs for seamless integration with your CI/CD or DevSecOps pipeline.The Dynamic Analyzer helps you to perform runtime security assessment and interactive instrumented testing.

关于run-time,可以用Frida or xPosedhook到使用私钥的代码处提取给攻击者服务器。

弗里达

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.

x姿势

Xposed is a framework that allows users to easily apply add-ons (called Modules) to the ROM. Rather than flashing a new ROM to get a specific feature, you can use Xposed to add individual features to whatever ROM you’re using, or even just the stock ROM.

2。在应用决策中

  1. App protects excel sheet with password and exports it.

Only excel sheets, which were exported with the supplied password can be imported again.

正如我之前在此回答中提到的,Frida 和 XPosed 可用于在 run-time 期间内省和检测代码。

攻击者可以使用其中一种工具来挂钩说明文档是否正确签名的函数,并且 return 总是 true,从而绕过所有预期的安全机制移动应用程序的代码。这是我之前提到的使用 Frida 或 xPosed 在 run-time.

期间提取私钥的替代方法

3。谁与什么正在访问后端服务器

  1. Users who want to export the excel must sign in using their Google Account with Google Sign in.
  2. My app requests a sign in token from google (verified by sha signature)
  3. Sign in token is sent to my server (HTTPS POST)
  4. My server verifies that the token is a valid one verified by Google. Documentation: https://developers.google.com/identity/sign-in/android/backend-auth

这 4 个步骤仅识别 请求中的人,换言之,请求的目标用户,但不提供任何形式的识别 什么代表用户提出了请求。

要获得更深入的解释,我建议您阅读我写的一篇文章,特别是该部分:Do You Know The Difference Between Who And What Is Communicating With Your Api Server?:

The who is the user of the mobile app that we can authenticate, authorize and identify in several ways, like using OpenID Connect or OAUTH2 flows.

The what is the thing making the request to the API server. Is it really a genuine instance of your mobile app, or is a bot, an automated script or an attacker manually poking around your API server with a tool like Postman?

您可能会惊讶于攻击者经常是您的真实用户试图绕过您的系统。

可能的解决方案

警告 1

要解决警告 1,您必须始终将私钥保存在您的后端服务器中,并且 从不 将其发送到移动应用程序的任何响应中。

警告 2

警告 2 可以通过不在移动应用程序中签署或验证文档来解决,而是在后端服务器中执行,并且您必须确保后端服务器知道什么 它正在发出请求。

警告 3

警告 3 已经部分解决,一旦您已经知道请求中的,您只需要实施一个可靠的解决方案来了解什么 它代表用户发出该请求。

识别什么它正在向后端服务器发出请求的最常见方法是在请求的header中使用一个秘密,你可能知道 APi-KeyAccess-Token 或任何其他选择的名称,但您可以在文章 Steal That Api Key With A Man In The Middle Attack 中看到如何通过中间人 (MitM) 攻击轻松绕过这种方法:

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.

可以使用更强大的解决方案,其中另一台服务器证明移动应用程序的完整性,这将允许后端服务器知道何时信任 什么 正在发出请求, 移动应用证明知道这个概念。

我写的一篇文章在 The Role of Mobile App Attestation:

部分更详细地解释了移动应用证明服务的作用

The role of a Mobile App Attestation service is to authenticate what is sending the requests, thus only responding to requests coming from genuine mobile app instances and rejecting all other requests from unauthorized sources.

In order to know what is sending the requests to the API server, a Mobile App Attestation service, at run-time, will identify with high confidence that your mobile app is present, has not been tampered/repackaged, is not running in a rooted device, has not been hooked into by an instrumentation framework(Frida, xPosed, Cydia, etc.), and is not the object of a Man in the Middle Attack (MitM). This is achieved by running an SDK in the background that will communicate with a service running in the cloud to attest the integrity of the mobile app and device it is running on.

On a successful attestation of the mobile app integrity, a short time lived JWT token is issued and signed with a secret that only the API server and the Mobile App Attestation service in the cloud know. In the case that attestation fails the JWT token is signed with an incorrect secret. Since the secret used by the Mobile App Attestation service is not known by the mobile app, it is not possible to reverse engineer it at run-time even when the app has been tampered with, is running in a rooted device or communicating over a connection that is the target of a MitM attack.

The mobile app must send the JWT token in the header of every API request. This allows the API server to only serve requests when it can verify that the JWT token was signed with the shared secret and that it has not expired. All other requests will be refused. In other words a valid JWT token tells the API server that what is making the request is the genuine mobile app uploaded to the Google or Apple store, while an invalid or missing JWT token means that what is making the request is not authorized to do so, because it may be a bot, a repackaged app or an attacker making a MitM attack.

虽然构建您自己的移动应用认证服务并不容易,但由知识渊博的工程师团队来做是可行的,要记住的主要事情是 SDK 不执行任何决定,只是响应服务器给出的随机挑战,它负责决定移动应用程序的完整性。

结论

您目前的防御措施比最初的要好,您还有改进的余地,您应该为提高移动应用程序和后端服务器的安全性付出多少努力,可能需要根据监管什么的法律进行权衡你在做什么,knowlo您和您的团队可用的 GE 和资源,并与您保护的价值成正比。

最后一点,我强烈建议您解决警告 1 和 2,并尝试解决警告 3。

加倍努力

我一直喜欢推荐这个非常有价值的资源OWASP Mobile Security Testing Guide

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