如果源代码可以进行逆向工程,那么加密Android(或Java)中的任何内容有什么意义?

Android和Java提供了一个加密API ,相对来说非常容易用于加密非专家。

但是,既然我们知道没有任何代码可以真正受到保护免受逆向工程,特别是用作种子或共享机密的字符串常量,我想知道:在Android应用程序中经历加密和解密的磨难有什么意义?

我错过了什么吗?

试图让我的问题更清晰,更具体:假设我有一个应用程序,其中代码和代码中使用某些字符串(即用户数据)需要保密:一种方法是在编译时以加密forms存储它们.apk并在运行时解密它们(使用模糊的硬编码密码)。 另一种方法是将它们以加密forms存储在远程服务器中,在运行时获取它们(通过Internet)并解密(使用共享密码)。

我认为两者之间没有太大区别,因为两者都要求(反向工程)代码中存在“密钥”。

这个问题有解决方案吗?

如果没有解决方案,为什么要加密?

这不是Android或Java的严格问题。 任何事情都可以逆转,如果它是本机代码,那就更难了。 请记住,他们甚至不必扭转它:你必须最终解密内存上的数据来操纵它。 此时,攻击者可以进行内存转储,他们将获取您的数据。 如果他们可以物理访问设备,并且您正在使用软件操作数据,那么您无法阻止它们。 对此的解决方案是使用防篡改或至少防篡改的专用硬件模块(HSM)(如果有人混淆它,它要么删除所有数据,要么至少保留事件的一些日志)。 它们有不同的形状和大小,从智能卡到网络连接设备,成本很高。 目前不适用于Android,但它可能会得到类似于TPM的东西,因此您可以安全地存储密钥并在硬件中进行加密操作。

因此,请考虑您的数据需要多大的秘密,并确定适当的保护级别。

您可能希望通过SSL下载它(这将在传输过程中保护它),确保您对服务器进行身份validation(因此您知道从受信任的地方获取正确的数据) 客户端(因此您可以确定您只是将数据提供给合适的人)。 您可以为此使用SSL客户端身份validation,它将比您(或任何不是加密专家的人)可能提供的任何自定义加密/密钥交换方案更安全。

加密API中的共享密钥不是你应该存储在应用程序中的东西(正如你所说,它很容易受到逆向工程的影响 – 尽管可能不像你期望的那样容易受到攻击;混淆非常容易)。

想象一下,您想在手机上创建/读取加密文件(对于您的秘密购物清单)。

创建一个后,使用主密码保存它(程序立即丢弃)。 然后,当您想要阅读它时,您必须重新输入主密码。 这是API所指的共享秘密,它与逆向工程完全相关。

您描述的问题有点类似于存储密码管理器问题的主密码 。

在这种情况下,提供的解决方案是使用salt进行密码哈希 。

ateiob无论何时将主密码存储在应用程序中,您实际上只是让未经授权的用户更难以访问加密数据。

首先,我们可以同意,使用嵌入在应用程序中的“主密钥”加密数据并将该数据存储在手机上,可以对“主密钥”进行逆向工程并对数据进行解密。

其次,我认为我们可以同意使用强加密,256位密钥和强密码,使用密码加密数据然后删除密码应该是相当安全的。 这两种技术都适用于移动设备上的编程。 事实上,iOS,支持开箱即用的BOTH需求。

 [keychainData setObject:@"password" forKey:(id)kSecValueData]; 

也许现实世界的例子可能有所帮助。

假设在低内存中必须保留和保护临时数据字段,可以使用主密码对其进行加密,并在用户清除临时数据字段时将其清除。 临时数据字段永远不会以纯文本格式存储。

因此,对于长期持久加密数据,有两个密码,一个主密码,嵌入在应用程序中用于临时短期加密和密码,通常必须由用户输入。

最后,如果要加密文件,请考虑添加另一级别的间接。 这样当前的密码用于加密用于加密所有用户文件的随机密钥。 这允许用户在不需要解密的情况下更改密码,加密所有加密文件。

假定攻击者拥有您的代码副本。 您的数据的保密性应完全取决于密钥。 见Kerckhoffs的原理 。

要保守密钥,您必须将其与代码分开。 记住它。 把它放在钱包里的一张纸上。 将它存放在通常放在保险箱中的USB记忆棒上。 使用像PasswordSafe这样的程序。 有很多种可能性。

当然有可能让任何攻击者通过多层密钥工作,以获得她实际需要的密钥。 PasswordSafe和类似的是一个这样的选择。 您会注意到此类程序没有为您提供“记住密码”的选项。