【问题标题】:Where to keep static information securely in Android app?在 Android 应用程序中哪里可以安全地保存静态信息?
【发布时间】:2020-08-26 16:03:58
【问题描述】:

在我的 Andorid 应用程序中,我使用少量密钥和令牌进行身份验证和初始化。我需要将这些静态密钥安全地存储在应用程序的某个位置。同时,我也需要在代码中访问它。 我知道我现在使用的 SharedPreference 和 Gradle 变量。我也尝试过 Cryptography,但是我还必须存储 secretKey 以进行解密。
因此,我正在寻找任何解决方法或适当的解决方案。任何帮助将不胜感激。

【问题讨论】:

  • “静态键”意味着您将它们定义为 APK 中某处的字符串(Java、res、...)?如果是,则实际上不可能将它们隐藏在某个地方。每个人都可以反编译你的应用程序并找到它。我建议您从某个安全来源远程获取密钥。
  • 看看这个:developer.android.com/training/articles/keystore。您可以加密您的数据并将密钥安全地存储在 AndroidKeyStore 中。
  • @skywall 知道了。如果有其他选择,我可以避免 api 调用。这就是为什么!
  • @НиколайГольцев 我以前试过。加密的数据在应用程序的某个地方,用于解密的私钥在应用程序中,解密的逻辑也在代码中。在那种情况下,我没有确保任何东西!如有错误请指正!
  • ...首先,Android Keystore 通过防止从应用程序进程和整个 Android 设备中提取密钥材料来减少未经授权使用 Android 设备之外的密钥材料。其次,Android KeyStore 通过让应用程序指定对其密钥的授权使用,然后在应用程序的进程之外执行这些限制,从而减少了对 Android 设备上密钥材料的未经授权的使用……这还不够吗?解密逻辑总是在代码中,还能在哪里?

标签: android security encryption access-token secret-key


【解决方案1】:

您的问题

在 Android 应用中安全保存静态信息的位置?

无论您将它们存储在何处以及如何存储,因为从您发布移动应用的那一刻起,其上的任何秘密现在都属于公共领域。

我也尝试过 Cryptography,但我还必须存储 secretKey 以进行解密。

您可以通过将其隐藏在 C 代码中,使用 Android 中的 JNI/NDK 接口来使其难以通过静态分析进行逆向工程,就像我在这个 Currency Converter Demo 存储库中所做的那样,但是如果攻击者无法要以这种方式对其进行逆向工程,他将在运行时使用检测框架进行此操作,流行的一种是Frida

将您自己的脚本注入黑盒进程。挂钩任何功能、监视加密 API 或跟踪私有应用程序代码,无需源代码。编辑,点击保存,立即查看结果。所有这些都无需编译步骤或程序重新启动。

另一种选择是尝试在运行时计算密钥,但随后 Frida 将再次挂钩执行此操作的函数并从其返回值中提取密钥。

在运行时计算 HMAC 的基本代码示例可以在ShipFast Demo repo 中找到:

private fun calculateAPIRequestHMAC(url: URL, authHeaderValue: String): String {

        val secret = JniEnv().getHmacSecret()
        var keySpec: SecretKeySpec

        // Configure the request HMAC based on the demo stage
        when (currentDemoStage) {
            DemoStage.API_KEY_PROTECTION, DemoStage.APPROOV_APP_AUTH_PROTECTION -> {
                throw IllegalStateException("calculateAPIRequestHMAC() not used in this demo stage")
            }
            DemoStage.HMAC_STATIC_SECRET_PROTECTION -> {
                // Just use the static secret to initialise the key spec for this demo stage
                keySpec = SecretKeySpec(Base64.decode(secret, Base64.DEFAULT), "HmacSHA256")
                Log.i(TAG, "CALCULATE STATIC HMAC")
            }
            DemoStage.HMAC_DYNAMIC_SECRET_PROTECTION -> {
                Log.i(TAG, "CALCULATE DYNAMIC HMAC")
                // Obfuscate the static secret to produce a dynamic secret to initialise the key
                // spec for this demo stage
                val obfuscatedSecretData = Base64.decode(secret, Base64.DEFAULT)
                val shipFastAPIKeyData = loadShipFastAPIKey().toByteArray(Charsets.UTF_8)
                for (i in 0 until minOf(obfuscatedSecretData.size, shipFastAPIKeyData.size)) {
                    obfuscatedSecretData[i] = (obfuscatedSecretData[i].toInt() xor shipFastAPIKeyData[i].toInt()).toByte()
                }
                val obfuscatedSecret = Base64.encode(obfuscatedSecretData, Base64.DEFAULT)
                keySpec = SecretKeySpec(Base64.decode(obfuscatedSecret, Base64.DEFAULT), "HmacSHA256")
            }
        }

        Log.i(TAG, "protocol: ${url.protocol}")
        Log.i(TAG, "host: ${url.host}")
        Log.i(TAG, "path: ${url.path}")
        Log.i(TAG, "Authentication: $authHeaderValue")

        // Compute the request HMAC using the HMAC SHA-256 algorithm
        val hmac = Mac.getInstance("HmacSHA256")
        hmac.init(keySpec)
        hmac.update(url.protocol.toByteArray(Charsets.UTF_8))
        hmac.update(url.host.toByteArray(Charsets.UTF_8))
        hmac.update(url.path.toByteArray(Charsets.UTF_8))
        hmac.update(authHeaderValue.toByteArray(Charsets.UTF_8))
        return hmac.doFinal().toHex()
    }

请记住,这是一个简单的解决方案,但即使是复杂的解决方案也容易受到攻击者使用的 Frida 脚本的攻击。

深度安全

所以,我正在寻找任何解决方法或适当的解决方案。任何帮助将不胜感激。

安全就是要尽可能多地添加层,以使攻击者花费时间来克服所有这些层,并提高攻击者所需技能集的标准。

因此,使用 C 代码隐藏秘密(如解密密钥)将加密的秘密存储在 Android 密钥库中会丢弃脚本孩子,但会使您容易受到知道如何使用 Frida 脚本挂钩您的代码的攻击者的攻击。

在我的 Andorid 应用程序中,我使用少量密钥和令牌进行身份验证和初始化。

如果您正在尝试保护访问 API 的密钥,那么您可以阅读 my answerthis question 以了解实施移动应用程序证明概念将使您无需存储秘密即可访问您的 API 服务器。出于初始化目的,我建议您将此逻辑移至后端,因为任何应用内决策都可以通过检测框架修改/绕过

还可以考虑对您的所有代码库使用强混淆技术,这将在攻击者对您的移动应用进行逆向工程的步骤中增加另一层难度。

您想加倍努力吗?

在回答安全问题时,我总是喜欢参考 OWASP 基金会的出色工作。

对于移动应用

OWASP Mobile Security Project - Top 10 risks

OWASP 移动安全项目是一个集中资源,旨在为开发人员和安全团队提供构建和维护安全移动应用程序所需的资源。通过该项目,我们的目标是对移动安全风险进行分类并提供开发控制以减少其影响或被利用的可能性。

OWASP - Mobile Security Testing Guide:

移动安全测试指南 (MSTG) 是一本用于移动应用安全开发、测试和逆向工程的综合手册。

对于 APIS

OWASP API Security Top 10

OWASP API 安全项目旨在通过强调不安全 API 的潜在风险并说明如何降低这些风险,为软件开发人员和安全评估人员提供价值。为了实现这一目标,OWASP API 安全项目将创建和维护一份 API 安全风险前 10 名文档,以及一个文档门户,用于在创建或评估 API 时提供最佳实践。

【讨论】:

    猜你喜欢
    • 2013-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-22
    相关资源
    最近更新 更多