保护Android应用程序敏感数据的最佳方法?
是的,这是一个相当普遍的问题,但我试图感受最好的方式来处理一个应用程序接触到基地/一个Web服务器,分发敏感的数据到应用程序。 任何链接,一般信息咨询等..将不胜感激。
由于应用程序会存储一段时间内从数据库中获取的持久数据,所有事情都变得有些棘手。
将敏感数据存储在设备上
这很大程度上取决于你的观众。 通常,Android操作系统禁止应用程序通过经过validation的Linux文件权限访问彼此的文件(即数据库,首选项文件,存储在应用程序专用目录中的常规文件)。 但是,在根设备上,应用程序可以获得root访问权限并读取所有内容。 有几件事要考虑:
- 如果你知道你的用户没有root权限(例如,如果你不是通过Android Market发布应用程序,而只是在你的公司,或类似的东西),你可以简单地依靠Android的基于文件系统的安全性。
- 如果用户获得root访问权限,他将非常小心他给予该特权的应用程序
- 如果一个应用程序没有获得root权限,它可能会造成很大的破坏。 在您的应用程序中的信息可能是用户的担忧最less。
- 生根导致零保修。 包括在应用程序。 您无法对根植于手机的信息泄露负责。
总而言之,如果你的信息不是超级敏感的(例如信用卡信息),我build议你坚持使用Android提供的默认安全性(即以纯文本保存所有内容,知道其他应用程序无法访问它)。
否则,encryption是要走的路。 这不是100%的安全(黑客可以解开你的应用程序,并找出如何解密数据),但这是一个重大的痛苦,破解,并将阻止大多数黑客。 尤其是如果你用ProGuard之类的东西来混淆你的代码。
将敏感数据从服务器传输到设备
你在这里有几个select。 首先,总是使用HTTPS。 启用HTTPS之后,我会提出两个额外的安全措施:
- 使用API密钥系统。 在您的所有请求中包含此API密钥并在发送任何回复之前在服务器端进行检查。 请记住,由于您使用的是HTTPS,因此攻击者无法仅使用networking嗅探器来查找您的API密钥。 但是,如果有人反编译你的应用程序,这是很容易的,这就是为什么你可以进一步混淆它(除了使用ProGuard)。 例如,您可以将API密钥分解为代码(例如,作为两个或三个类中的静态成员)。 然后,当您发送请求时,您只需连接所有这些部分。 你甚至可以应用一些其他types的转换(例如位移),以便更难从反编译的代码中找出。
- 每次发送请求时都可以生成一个密钥。 这个密钥可以通过使用一些只有你知道的逻辑来生成,这样你才能在客户端和服务器端实现它。 例如,请求可能包含以下参数:
time=1321802432&key=[generated-key]
其中generated-key
是从time
参数生成的。 例如:md5(time + salt)
。 当服务器收到这个请求时,它可以做两件事情:- 检查
key
是否等于md5(time + salt)
(请注意,只有客户端和服务器知道salt,并且可以像上面的API密钥一样对其进行模糊处理),以及 - 检查过去的
time
不算太早(例如,如果过去超过1-2分钟,请将请求视为无效)。
- 检查
第二种方法更有用,如果你也在做简单的HTTP请求,每个人都可以看到发送的参数。 而且,从反编译的代码中找出更困难。 特别是如果您将关键计算逻辑分布在多个类中。
但是请注意, 没有任何东西可以破解你的应用程序。 您可以尽可能多地混淆,如果黑客真的确定要获取您的数据,那么他将能够通过反编译您的应用程序,并花费许多不眠之夜来通过您的代码,并弄清楚请求是如何形成的。 确保数据安全的唯一方法是向用户提供一个密码,除了完成上面所写的所有工作外。 你不能从反编译的代码中得到只存在于某人(用户)头部的密码:)。
(来这里感谢谷歌search)
最近我一直在研究这个问题,这个页面已经出现了很多,这要归功于Google和Bing的search。 被广泛接受的在设备上安全地存储数据的过程一直使用像AES这样的强encryptionalgorithm。 更难的问题是“AES需要一个安全的密钥,你对密钥做了什么?
谷歌最近宣布了一个基于云的存储解决scheme的应用程序,所以你可以考虑在那里存储密钥,如果情况允许的话。 否则,似乎在设备外部获取密钥(比如在服务器上)更好。 如果你能让用户打个人识别号码,那实际上效果最好。 您可以进行密码派生以存储密码,您可以重新派生以validation密码
如果没有“用户在PIN码上打字”的部分,我还没有find很好的答案。 但是,如果您必须在应用程序中存储一个密码,请勿硬编码密钥。 至less使用安全密码生成器和/或派生函数(如PBKDF2(基于密码的派生函数2))生成密钥。
如果我正确地阅读了文章,Google确实说过,一种方法是在应用程序第一次启动时生成密钥,通过MODE_PRIVATE标志将密钥存储到大量文件I / O操作中,然后将其用作密钥。 你也可以根据这个主密钥派生出其他的密钥,而NIST实际上就是根据这个密码build议的。
是否相信主密钥方法,我会留给你。 这个密钥将暴露在根源设备上。 我也承认我还在研究这个问题
在HTTPS上使用SSL来传输数据而不是HTTP,您需要在networking服务器上设置证书,不太确定它是如何工作的。
如果您真的关心这些数据,那么在发送和解密到达应用程序之前,会使用唯一的algorithm对其进行进一步encryption。 我想这是所有关于它..除非你需要一些真正强大的,然后开发自己的协议基于TCP和/或使用另一个端口..也许这将有助于
http://en.wikipedia.org/wiki/Secure_Sockets_Layer http://developer.android.com/reference/javax/net/ssl/package-summary.html http://blog.synyx.de/2010/06/机器人和自签署的SSL-证书/
至于在应用程序中存储数据,您可以在存储之前encryption数据,或者您可以使用SQLite以外的其他格式来提高安全性,因为您可以使用浏览器轻松查看sqlite数据库。
除非电话根深蒂固,否则不应该有办法从中提取数据。
如果您希望确保用户无法通过查看应用程序来查看数据,那么encryption确实是唯一的方法。 即使是“受保护”的存储设备,如果设备是根植的,用户也可以访问。 即使encryption也不完全安全,因为您需要在某个时刻解密数据才能显示数据。 你会劝阻随便的浏览器,而不是确定的黑客。
Android上的每个应用程序都在安全的沙箱环境中运行,因此系统上的其他进程无法正确握手就无法访问您的代码或私有数据。 但是应用程序的糟糕devise仍然存在很多漏洞。 这个来自Android开发者网站的链接build议你一些安全的好的提示 – https://developer.android.com/training/articles/security-tips.html