我正在创建一个应用程序,它是一个密码管理器,用户输入的所有数据都存储在SQLite数据库中
在没有任何加密的情况下将数据保存在数据库中是否安全,以便没有其他应用程序或其他Web攻击可以访问非root电话中的数据库文件?
如果它不安全那么数据可以安全地存储在SQLite数据库中的可能方式是什么?
答案 0 :(得分:2)
借助SharedPreferences界面,Android平台提供了一种存储首选项甚至大文件的便捷方式。即使存储在这些共享首选项中的数据隐藏在屏蔽目录中,也可以在设备植根时轻松检索数据。
因此,如果应用程序存储的信息是敏感的,则可能需要加密存储在共享首选项中的数据。可以通过两种方式实现:
使用加密库加密/解密SharedPreferences的值(以及最终的密钥)。有许多最先进的java加密库javax.crypto,Bouncycastle 2和隐藏[3] 使用提供SharedPreferences包装器的库。这些库非常方便,因为开发人员不必关心必须使用哪种算法。同时,使用这些库可能导致缺乏灵活性,其中一些不使用安全算法。因此,他们可能不信任存储非常敏感的数据。提供这种包装功能的最常用库之一是SecurePrefences [4]。在您选择此解决方案时,您可以以非常直接的方式实例化扩展SharedPreferences的SecurePreferences: SecurePreferences securePreferences =新的SecurePreferences(上下文," MyPassword",null); 由GitHub主持的❤SecurePreferencesExample.java 这两种方法基于对称密码算法,例如AES(具有适当的密钥大小)。它导致了奇怪:我们应该使用哪个键?实际上,如果我们使用静态密钥,则可以通过对应用程序进行逆向工程来解密首选项。因此,最好的解决方案是使用用户在应用程序启动时必须键入的密码/密码。另一种可能性是使用指纹API [15](自API 23起可用),它提供了一种安全且流畅的身份验证方式。 不幸的是,这种方法无法满足每个应用程序的用户体验。例如,如果我们想要在键入密码之前显示一些信息,那么我们就不能使用这种安全的加密系统。
希望Android提供一种安全的方式来生成一个密钥,该密钥对于每个应用程序/设备都是唯一的:KeyStore。 Android KeyStore的目标是允许应用程序将私钥放在其他应用程序无法检索的位置,或者通过实质访问存储在设备上的数据。该机制非常简单:第一次运行应用程序以检查链接到应用程序的私钥是否存在。如果没有,则生成一个并将其存储在KeyStore中。如果私钥已经存在,则可以使用它作为加密安全密钥来解密SharedPreferences数据,这要归功于上述算法。 Obaro Ogbo写了一篇详细的文章[11],深入介绍了如何使用KeyStore生成私有/公钥对。 KeyStore的主要缺点是它仅在API 18之后可用。但是,有一个backport库提供兼容性,因为API 14 [14](这不是“官方”的后端,所以你必须自己承担使用它的风险)。
因此,在决定应该使用哪种类型的偏好系统时,我们可以提出以下决策图:
安全偏好设置流程图
答案 1 :(得分:0)
为什么不加密密码数据? 密码信息太敏感了。我想你可以尝试使用RSA算法,使用长密钥,至少1024位。