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