Android和Java提供crypto API,这对于加密非专家来说相对容易使用。
但是既然我们知道没有任何代码可以真正受到保护免受逆向工程,特别是用作种子或共享机密的字符串常量,我想知道:在Android应用程序中经历加密和解密的磨难有什么意义? / p>
我错过了什么吗?
尝试让我的问题更清晰,更具体:假设我有一个应用程序,其中某些字符串使用 代码 代码(即不用户数据)需要保密:一种方法是将它们以加密形式存储在已编译的.apk
中,并在运行时解密它们(使用模糊的硬编码密码) 。另一种方法是将它们以加密形式存储在远程服务器中,在运行时获取它们(通过Internet)并解密(使用共享密码)。
我认为两者之间没有太大区别,因为两者都要求(反向工程)代码中存在“密钥”。
这个问题有解决方法吗?
如果没有解决方案,为什么要加密?
答案 0 :(得分:5)
这不是Android或Java的严格问题。任何事情都可以逆转,如果是原生代码,那就更难了。请记住,他们甚至不必扭转它:你必须最终解密内存上的数据来操纵它。此时,攻击者可以进行内存转储,他们将获取您的数据。如果他们可以物理访问设备,并且您正在操作软件中的数据,那么您无法阻止它们。对此的解决方案是使用专用的硬件模块(HSM),该模块具有防篡改功能或至少是防篡改功能(如果有人使用它,它会删除所有数据或至少保留一些数据)事件的日志)。它们有不同的形状和大小,从智能卡到网络连接设备,成本很多。目前不适用于Android,但也许它会得到类似于TPM的东西,因此您可以安全地存储密钥并在硬件中进行加密操作。
因此,请考虑您的数据需要多大的秘密,并确定适当的保护级别。
您可能希望通过SSL下载它(在传输过程中保护它),确保您对服务器进行身份验证(因此您知道从受信任的地方获取正确的数据)和客户端(因此您可以确定您只是将数据提供给合适的人)。您可以为此使用SSL客户端身份验证,它将比您(或任何不是加密专家的人)可能附带的任何自定义加密/密钥交换方案更安全。
答案 1 :(得分:3)
加密API中的共享密钥不会存储在应用程序中(正如您所说, 容易受到逆向工程的影响 - 尽管可能不像您那样容易受到攻击期待;混淆很容易)。
想象一下,您想要在手机上创建/读取加密文件(用于您的秘密购物清单)。
创建一个后,使用主密码保存它(程序立即丢弃)。然后,当您想要阅读它时,您必须重新输入主密码。这是API所指的共享秘密,它与逆向工程完全相关。
答案 2 :(得分:2)
您所描述的问题与密码管理器问题的storing a master password有些类似。
在这种情况下,提供的解决方案是使用salt for password hashes。
答案 3 :(得分:1)
ateiob无论何时将主密码存储在应用程序中,您实际上只是让未经授权的用户更难以访问加密数据。
首先,我们可以同意,使用嵌入在应用程序中的“主密钥”对数据进行加密并将该数据存储在手机上,可以对“主密钥”进行逆向工程并对数据进行解密。
其次我认为我们可以同意使用强加密,256位密钥和强密码,使用密码加密数据然后删除密码应该是相当安全的。这两种技术都适用于移动设备上的编程。事实上,iOS,支持开箱即用的BOTH需求。
[keychainData setObject:@"password" forKey:(id)kSecValueData];
也许现实世界的例子可能有所帮助。
假设在低内存中必须保留和保护临时数据字段,可以使用主密码对其进行加密,并在用户清除临时数据字段时将其清除。临时数据字段永远不会以纯文本形式存储。
因此,对于长期持久加密数据,有两个密码,一个主密码,嵌入在应用程序中用于临时短期加密和密码,通常必须由用户输入。
最后,如果要加密文件,请考虑添加另一级别的间接。这样当前的密码用于加密用于加密所有用户文件的随机密钥。这允许用户更改密码而无需解密,加密所有加密文件。
答案 4 :(得分:-1)
假设攻击者拥有您的代码副本。您的数据的保密性应完全取决于密钥。请参阅Kerckhoffs's Principle。
要保守密钥,您必须将其与代码分开。记住它。把它放在钱包里的一张纸上。将它存放在通常放在保险箱中的USB记忆棒上。使用PasswordSafe之类的程序。有很多种可能性。
当然可以让任何攻击者通过多层密钥工作,以获得她实际需要的密钥。 PasswordSafe和类似的是一个这样的选择。您会注意到此类程序不为您提供“记住密码”的选项。