android - 如何保护 Android 应用程序中的 key ?

标签 android security authentication backend secret-key

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

  • 想要导出 Excel 的用户必须使用他们的 Google 帐户和 Google Sign in 登录。
  • 我的应用程序从谷歌请求登录 token (由 sha 签名验证)
  • 登录 token 发送到我的服务器(HTTPS POST)
  • 我的服务器验证 token 是由 Google 验证的有效 token 。
    文档:https://developers.google.com/identity/sign-in/android/backend-auth
  • 以 JSON 格式(HTTPS POST)发回应用程序帐户信息和 excel 导出密码
  • 应用程序使用密码保护 Excel 工作表并将其导出。

  • 只有使用提供的密码导出的 Excel 工作表才能再次导入。

    我也有一个 PDF 导出功能。 PDF 应由应用程序签名。该过程与以前相同,但使用 pkcs key ,其中包含私钥和公钥作为 base64 字符串。

    Root 设备怎么样,攻击者可能会得到发送的密码/pkcs key ?

    最佳答案

    可能的注意事项

    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?


    乍一看:
  • 从私钥离开您的后端服务器的那一刻起,它就属于公共(public)域,因此必须将其视为已泄露。
  • 移动应用程序正在做出重要决策、签署文档并验证其签名,而这可以在运行时通过 Frida 和 xPosed 等检测框架绕过。
  • 后端服务器只对请求中的用户进行身份验证,而不是 什么 它正在提出请求。

  • 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.


    私钥可以保密的唯一方法是将它安全地存储在打算使用的地方,我强烈建议在使用它的同一个地方生成它,也就是同一个服务器。
    从私钥离开后端服务器的那一刻起,它就不再安全存储,现在任何有技能和知识的人都可以使用大量开源和付费工具进行静态二进制文件的逆向工程,甚至对其进行自省(introspection)在运行时,改变他们的行为或提取数据,也就是你的私钥。
    对于静态二进制分析,我们有一个开源工具 MobSF ,它结合了其他几个开源工具,可以从静态二进制文件中反编译、分析和提取数据。
    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.


    关于运行时,可以使用 FridaxPosed Hook 到使用私钥的代码位置并将其提取到攻击者服务器。
    弗里达

    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.


    xPosed

    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 可用于在运行时内省(introspection)和检测代码。
    攻击者可以使用其中一种工具来钩住表示文档是否正确签名的函数,并始终返回 true ,从而绕过移动应用程序代码中提供的所有预期安全机制。这是我之前提到的使用 Frida 或 xPosed 在运行时提取私钥的另一种方法。
    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 中使用了一个 secret ,您可能知道它是 APi-Key , Access-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 不执行任何决策,只是响应由服务器,它负责决定移动应用程序的完整性。
    结论
    您当前的防御比最初的防御要好,您还有改进的空间,您应该投入多少努力来提高移动应用程序和后端服务器的安全性,这可能需要与规范您正在做的事情的法律保持平衡,您和您的团队可用的知识和资源,并且与您所保护的事物的值(value)成正比。
    最后,我强烈建议您解决警告 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.

    关于android - 如何保护 Android 应用程序中的 key ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59556927/

    相关文章:

    android - 在 React Native 中取消焦点文本输入

    android - 每 N 秒更新一次 TextView?

    android - Android 中的 TextWatcher 警告和慢速类型

    javascript - 使用 JavaScript 创建 IFRAME 的最佳做法是什么?

    authentication - Azure Web 应用程序网关身份验证

    python 请求登录认证

    android - React-Native(Android)-任务 ':app:transformClassesWithMultidexlistForRelease'的执行失败

    security - 在 Glassfish 上进行 Realm 身份验证后重定向

    php - 如何防止跨域ajax请求?

    android - 在 Mifare Ultralight C 上限制写入时读取