在 Android 应用程序中存储秘密和凭据
Storing secrets and credentials inside of an Android App
我正在使用 AWS Cognito,我需要在我的 android 应用程序中的某处存储一些凭据和机密,以便稍后使用它们将 in/sign up/log 用户注销。
一些消息来源建议将凭据存储在项目 gradle.properties 文件中。凭据将从那里检索为 BuildConfig.FIELD_NAME
。我可以 100% 确定在对 apk 进行逆向工程时无法从中提取这些信息吗?
我考虑的另一种方法是使用非对称加密算法(使用 public-私钥)加密凭据,并在需要时在运行时解密它们,但同样,我需要存储在我的某个地方应用 public 密钥以解密凭据。这不再有效,因为可以在反编译 apk 时提取 public 密钥。
我对此进行了大量研究,但在这种情况下我没有找到任何帮助。几乎每篇文章都提到如何存储密码等凭据,但情况不同,因为我不会在运行时从服务器或任何地方检索我的秘密和凭据。进行 API 调用以获取凭据又是一件坏事。
那么,我怎样才能尽可能安全地执行此操作?
我在等你的解决方案!谢谢
编辑:
密钥存储并没有真正起作用,因为我必须在将它们添加到密钥存储之前从某个地方获取秘密
这实际上完全取决于您需要或希望您的应用程序的安全性,以及这些凭据的敏感度。由于无法从服务器端存储和检索它们,因此最好的办法是将它们嵌入代码中的某个位置。 APK 可以很容易地反编译,因此您的凭据将始终可以通过某种方式访问。真正的问题是你希望逆向过程有多难。
From there the credentials will be retrieved as BuildConfig.FIELD_NAME. Can I be 100% sure that those cannot be extracted from the apk when reverse-engineering it?
我 100% 确定它可以找回 :)。 Java 不会加密任何字符串,它们都将作为原始文本存储在 dex 文件中,准备好进行 grep。
接下来,您的下一步是使用静态密钥对代码中的密钥进行加密。有些工具可以为您做到这一点,例如 DexGuard、Dasho、Dexprotector——您也可以提出自己的解决方案。This article 解释得很好。
请记住,您自己的解决方案或第三方工具提供的解决方案都可能很容易逆转:请参阅 this example 了解 DexGuard。另请注意,在运行时解密时,这些凭据将在设备的 RAM 中清晰显示,从而允许调试器轻松读取它们。
您的下一个最佳选择是在本机代码中使用加密字符串:更难逆转和追踪,但仍然可行。
然后您可以使用白盒加密,同样使用第三方工具,例如 Inside Secure 提出的那些工具。这实际上会将加密算法和密钥混合到混淆的本机代码中,这可能会让您难以逆向和调试 encryption/decryption 方法。在这里,您只会在您的应用程序中包含加密的凭据,并且它们会在白盒内安全地解密。白盒通常非常安全(但 并非 无法破解),但一旦解密,凭据将在设备内存中清晰可见。这将更彻底地防止简单的反编译。
然后...如果不涉及硬件解决方案(KeyStore、嵌入式安全元件)和服务器来备份所有内容,我认为您不能走得更远。
我正在使用 AWS Cognito,我需要在我的 android 应用程序中的某处存储一些凭据和机密,以便稍后使用它们将 in/sign up/log 用户注销。
一些消息来源建议将凭据存储在项目 gradle.properties 文件中。凭据将从那里检索为 BuildConfig.FIELD_NAME
。我可以 100% 确定在对 apk 进行逆向工程时无法从中提取这些信息吗?
我考虑的另一种方法是使用非对称加密算法(使用 public-私钥)加密凭据,并在需要时在运行时解密它们,但同样,我需要存储在我的某个地方应用 public 密钥以解密凭据。这不再有效,因为可以在反编译 apk 时提取 public 密钥。
我对此进行了大量研究,但在这种情况下我没有找到任何帮助。几乎每篇文章都提到如何存储密码等凭据,但情况不同,因为我不会在运行时从服务器或任何地方检索我的秘密和凭据。进行 API 调用以获取凭据又是一件坏事。
那么,我怎样才能尽可能安全地执行此操作? 我在等你的解决方案!谢谢
编辑: 密钥存储并没有真正起作用,因为我必须在将它们添加到密钥存储之前从某个地方获取秘密
这实际上完全取决于您需要或希望您的应用程序的安全性,以及这些凭据的敏感度。由于无法从服务器端存储和检索它们,因此最好的办法是将它们嵌入代码中的某个位置。 APK 可以很容易地反编译,因此您的凭据将始终可以通过某种方式访问。真正的问题是你希望逆向过程有多难。
From there the credentials will be retrieved as BuildConfig.FIELD_NAME. Can I be 100% sure that those cannot be extracted from the apk when reverse-engineering it?
我 100% 确定它可以找回 :)。 Java 不会加密任何字符串,它们都将作为原始文本存储在 dex 文件中,准备好进行 grep。
接下来,您的下一步是使用静态密钥对代码中的密钥进行加密。有些工具可以为您做到这一点,例如 DexGuard、Dasho、Dexprotector——您也可以提出自己的解决方案。This article 解释得很好。
请记住,您自己的解决方案或第三方工具提供的解决方案都可能很容易逆转:请参阅 this example 了解 DexGuard。另请注意,在运行时解密时,这些凭据将在设备的 RAM 中清晰显示,从而允许调试器轻松读取它们。
您的下一个最佳选择是在本机代码中使用加密字符串:更难逆转和追踪,但仍然可行。
然后您可以使用白盒加密,同样使用第三方工具,例如 Inside Secure 提出的那些工具。这实际上会将加密算法和密钥混合到混淆的本机代码中,这可能会让您难以逆向和调试 encryption/decryption 方法。在这里,您只会在您的应用程序中包含加密的凭据,并且它们会在白盒内安全地解密。白盒通常非常安全(但 并非 无法破解),但一旦解密,凭据将在设备内存中清晰可见。这将更彻底地防止简单的反编译。
然后...如果不涉及硬件解决方案(KeyStore、嵌入式安全元件)和服务器来备份所有内容,我认为您不能走得更远。