保护Android应用敏感数据的最佳方法?

时间:2011-11-18 15:05:34

标签: android security

是的,这是一个相当普遍的问题,但我正在尝试了解处理触摸基础的应用程序的最佳方式,该应用程序将敏感数据分发到应用程序。任何链接,一般信息建议等..将不胜感激。

由于app会存储从数据库中恢复的持久数据一段时间......所有内容都变得有点敏感。

5 个答案:

答案 0 :(得分:97)

在设备上存储敏感数据

这在很大程度上取决于您的受众。通常,Android OS禁止应用程序通过经过验证的Linux文件权限访问彼此的文件(即数据库,首选项文件,存储在应用程序私有目录中的常规文件)。但是,在有根设备上,应用程序可以获取root访问权限并读取所有内容。需要考虑的一些事项:

  1. 如果您知道您的用户不会拥有root用户(例如,如果您没有通过Android Market分发应用程序,但仅限于您的公司,或类似的东西),您可以简单地依赖Android基于文件系统的安全性。 / LI>
  2. 如果用户确实获得了root权限,那么他会非常小心他提供的权限
  3. 如果某个应用确实获得root访问权限,则会造成很大的破坏。您的应用中的信息可能是用户最不担心的。
  4. 生根导致零保修。包括在应用程序中。您不能对在有根电话上泄露信息负责。
  5. 总而言之,如果您的信息不是超级敏感的(例如信用卡信息),我建议您坚持使用Android提供的默认安全性(即以纯文本保存所有内容,知道其他应用无法访问它)。

    否则,加密是可行的方法。这不是100%安全(黑客可以解组你的应用程序并弄清楚如何解密数据),但这是一个很大的痛苦,破解并将阻止大多数黑客。特别是如果您使用ProGuard等内容对代码进行模糊处理。


    将敏感数据从服务器传输到设备

    这里有几个选项。首先,始终使用HTTPS。启用HTTPS后,我建议采取两种额外的安全措施:

    1. 使用API​​密钥系统。在所有请求中包含此API密钥,并在发送任何响应之前在服务器端进行检查。请记住,由于您使用的是HTTPS,攻击者无法使用网络嗅探器来查找您的API密钥。但是,如果有人反编译您的应用程序,这很容易理解,这就是为什么您可以进一步混淆它(除了使用ProGuard)。例如,您可以将API密钥分解为代码周围的部分(例如,作为两个或三个类中的静态成员)。然后,当您发送请求时,您只需连接所有这些部分。您甚至可以应用其他类型的转换(例如位移),以便更难以从反编译代码中找出。
    2. 每次发送请求时都可以生成密钥。该密钥将通过使用只有您知道的一些逻辑生成,以便您也可以在客户端和服务器端实现它。例如,请求可以包括以下参数:
      time=1321802432&key=[generated-key]
      generated-key参数生成time的位置。例如:md5(time + salt)。当服务器收到此请求时,它可以做两件事:
      1. 检查key是否确实等于md5(time + salt)(请注意,只有客户端和服务器知道盐,并且它可以与上面的API密钥类似地进行模糊处理),并且
      2. 检查time过去不是太远(例如,如果过去超过1-2分钟,请认为请求无效)。
    3. 如果您还要执行普通的HTTP请求,那么第二种方法会更有用,每个人都可以看到正在发送的参数。而且,从反编译代码中找出它要困难得多。特别是如果您将密钥计算逻辑分布在多个类中。

      然而,请注意会导致无法破解您的应用。您可以根据需要进行模糊处理,如果黑客确实确定要获取您的数据,他将能够通过反编译您的应用程序并花费许多不眠之夜通过您的代码并搞清楚请求是如何形成的。保护数据的唯一真正方式是向用户提供密码,除了完成我上面写的所有工作。您无法从反编译代码中获取仅存在于某人(用户)头部的密码:)。

答案 1 :(得分:12)

(感谢谷歌搜索来到这里)

我最近一直在研究这个问题,感谢谷歌和必应搜索,这个页面已经出现了很多。用于安全地在设备上存储数据的广泛接受的过程是使用诸如AES的强加密算法。更难的问题是“AES需要一个安全的密钥。你用钥匙做什么?”

谷歌最近发布了针对应用程序的基于云的存储解决方案,因此如果情况允许,您可以考虑将密钥存储在那里。否则,它似乎在服务器之外获取密钥更好。如果您可以让用户打入PIN,那实际上效果最好。您可以进行密码派生以存储密码,并且可以重做派生以验证密码

如果没有“用户在PIN中打孔”部分,我还没有找到很多这个问题的好答案。但是,如果您必须使用APP存储一个,请不要使用密钥。至少,使用安全密码生成器和/或类似PBKDF2(基于密码的派生函数2)的派生函数生成密钥。

如果我正确阅读帖子,Google确实说过一种方法是在应用程序第一次启动时生成密钥,通过MODE_PRIVATE标志将密钥存储到很多文件I / O操作中,并将其用作钥匙。您还可以基于该主密钥导出其他密钥,而NIST实际上也会根据这些内容提出建议。

是否信任主密钥方法,我会留给您。此密钥将在root设备上公开。我也承认我还在研究这个问题

答案 2 :(得分:1)

Android上的每个应用程序都在安全的沙箱环境中运行,因此如果没有正确的握手,系统上的其他进程将无法访问您的代码或私有数据。但是,由于应用程序设计不佳,仍然存在许多漏洞。 Android开发者网站提供的这个链接可以为您提供一些安全性方面的好建议 - https://developer.android.com/training/articles/security-tips.html

答案 3 :(得分:0)

如果您想要确保用户除了查看您的应用之外无法查看数据,那么加密确实是唯一的方法。即使是"受保护的"如果设备已植根,则用户可以访问存储。即使加密也不是完全安全的,因为您需要在某个时刻解密数据才能显示它。你会劝阻休闲浏览器,但不会劝阻黑客。

答案 4 :(得分:0)

在HTTPS上使用SSL来传输数据而不是HTTP,您需要在网络服务器上设置证书并不十分确定它是如何工作的。

如果您真的关心数据,那么在发送数据之前,请使用独特的算法对其进行进一步加密,然后在到达应用程序时对其进行解密。我猜这就是它的全部......除非你需要一些非常强大的东西,然后根据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/android-and-self-signed-ssl-certificates/

至于在应用程序中存储数据,您可以在存储之前加密数据,或者您可以使用除SQLite之外的其他格式以提高安全性,因为您可以非常轻松地使用浏览器查看sqlite数据库。

除非手机已植根,否则无法从中提取数据。