简体   繁体   English

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

[英]Best way to secure Android app sensitive Data?

Yes this is a pretty general question but I'm trying to get a feel for the best way to handle an app that touches base w/ a webserver that distributes sensitive data to the app. 是的,这是一个非常普遍的问题,但我正在试图找到一种最好的方法来处理触及基础的应用程序,该应用程序将敏感数据分发到应用程序。 Any links, general information advice etc.. would be appreciated. 任何链接,一般信息建议等..将不胜感激。

Since the app would store persistant data retreived from the database for a certain amount of time.. everything becomes somewhat touchy. 由于应用程序将存储从数据库中恢复的持久数据一段时间......所有内容都变得有些敏感。

Storing sensitive data on the device 在设备上存储敏感数据

That depends very much on your audience. 这在很大程度上取决于您的受众。 Normally, the Android OS prohibits apps from accessing each other's files (ie databases, preference files, regular files stored in the app's private directory) through proven Linux file permissions. 通常,Android OS禁止应用程序通过经过验证的Linux文件权限访问彼此的文件(即数据库,首选项文件,存储在应用程序私有目录中的常规文件)。 However, on rooted devices an application can obtain root access and read everything. 但是,在有根设备上,应用程序可以获取root访问权限并读取所有内容。 A few things to think about: 一些要考虑的事情:

  1. If you know your users won't have root (eg if you are not distributing the app through Android Market, but only in your company, or something like that), you can simply rely on Android's filesystem-based security. 如果您知道您的用户不会拥有root用户(例如,如果您不通过Android Market分发应用程序,但仅限于您的公司,或类似的东西),您可以简单地依赖Android的基于文件系统的安全性。
  2. If a user does get root access, he will be very careful what application he gives that priviledge to 如果用户确实获得root访问权限,那么他会非常小心他给予的特权应用程序
  3. If an app does get root access, it can wreak a lot of havoc. 如果一个应用程序确实获得root访问权限,它可能会造成很大的破坏。 The information in your app could be the least of the user's worries. 您应用中的信息可能是用户最不担心的问题。
  4. Rooting leads to zero warranty. 生根导致零保修。 Including in apps. 包括在应用程序中。 You can't be held responsible for leaking information on a rooted phone. 您不能对在有根电话上泄露信息负责。

To conclude, if your information is not super-duper sensitive (eg credit card information), I'd suggest just sticking with the default security provided by Android (ie save everything in plain text, knowing other apps can't access it). 总而言之,如果您的信息不是超级敏感的(例如信用卡信息),我建议您坚持使用Android提供的默认安全性(即以纯文本保存所有内容,知道其他应用无法访问它)。

Otherwise, encryption is the way to go. 否则,加密是可行的方法。 It's not 100% secure (a hacker could de-compile your app and figure out how to decrypt the data), but it's a major pain to crack and will stop most hackers. 这不是100%安全(黑客可以解组你的应用程序并弄清楚如何解密数据),但这是一个很大的痛苦,破解并将阻止大多数黑客。 Especially if you obfuscate your code with something like ProGuard . 特别是如果你用ProGuard之类的东西混淆你的代码。


Transferring sensitive data from the server to the device 将敏感数据从服务器传输到设备

You have a few options here. 你有几个选择。 First of all, always use HTTPS. 首先,始终使用HTTPS。 After enabling HTTPS, here are two extra security measures I would propose: 启用HTTPS后,我建议采取两种额外的安全措施:

  1. Use an API key system. 使用API​​密钥系统。 Include this API key in all your requests and check it on the server side before sending any response back. 在所有请求中包含此API密钥,并在发送任何响应之前在服务器端进行检查。 Remember that since you're using HTTPS, an attacker would not be able to just use a network sniffer to find out your API key. 请记住,由于您使用的是HTTPS,攻击者无法使用网络嗅探器来查找您的API密钥。 However, this is pretty easy to figure out if someone decompiles your app, which is why you can obfuscate it even further (besides using ProGuard). 但是,如果有人反编译您的应用程序,这很容易理解,这就是为什么您可以进一步混淆它(除了使用ProGuard)。 For example, you can keep the API key broken up into pieces all around your code (for example as static members in two or three classes). 例如,您可以将API密钥分解为代码周围的部分(例如,作为两个或三个类中的静态成员)。 Then, when you send a request, you just concatenate all those pieces. 然后,当您发送请求时,您只需连接所有这些部分。 You can even apply some other sort of transformation (eg bit shifting) to make it even harder to figure out from the decompiled code. 您甚至可以应用其他类型的转换(例如位移),以便更难以从反编译代码中找出。
  2. You can generate a key every time you send a request. 您可以在每次发送请求时生成密钥。 That key would be generated by using a bit of logic that only you know, so that you can implement it client- and server-side as well. 该密钥将通过使用只有您知道的一些逻辑生成,以便您也可以在客户端和服务器端实现它。 For example, a request could include the following parameters: 例如,请求可以包含以下参数:
    time=1321802432&key=[generated-key]
    where generated-key is generated from the time parameter. 其中generated-key是从time参数生成的。 For example: md5(time + salt) . 例如: md5(time + salt) When the server receives this request, it can do two things: 当服务器收到此请求时,它可以做两件事:
    1. Check that key is indeed equal to md5(time + salt) (note that only the client and the server know the salt and it can be obfuscated similarly to the API key above), and 检查key是否确实等于md5(time + salt) (请注意,只有客户端和服务器知道盐,并且它可以与上面的API密钥类似地进行模糊处理),并且
    2. Check that time is not too far back in the past (eg if it's more than 1-2 minutes in the past, consider the request invalid). 检查过去的time不是太远(例如,如果过去的时间超过1-2分钟,请考虑请求无效)。

The second method is more useful if you are also doing plain HTTP requests, where everyone can see the parameters being sent. 如果您还在进行纯HTTP请求,那么第二种方法会更有用,每个人都可以看到正在发送的参数。 Also, it's much harder to figure out from decompiled code. 而且,从反编译代码中找出它要困难得多。 Especially if you spread the key calculation logic across multiple classes. 特别是如果您将键计算逻辑分布在多个类中。

However , note that nothing makes it impossible to crack your app. 请注意, 没有什么能够破解你的应用程序。 You can obfuscate as much as you want, if a hacker is really determined to get to your data, he will be able to so by decompiling your application and spending many sleepless nights passing through your code and figuring out how the requests are formed. 您可以根据需要进行模糊处理,如果黑客真的决心获取您的数据,他将能够通过反编译您的应用程序并花费许多不眠之夜通过您的代码并弄清楚请求是如何形成的。 The only real way of securing your data is by asking your user for a password, besides doing all the work I wrote about above. 保护数据的唯一真正方法是向用户提供密码,除了完成我上面写的所有工作。 You can't get a password that only exists in someone's (the user) head from decompiled code :). 您无法从反编译代码中获取仅存在于某人(用户)头部的密码。

(Came here thanks to a Google search) (来自Google搜索)

I've been researching this a lot lately and this page has come up a lot thanks to Google and Bing searches. 我最近一直在研究这个问题,感谢Google和Bing的搜索,这个页面已经出现了很多。 The widely-accepted procedure for storing data on the device securely has been to use a strong encryption algorithm like AES. 用于安全地在设备上存储数据的广泛接受的过程是使用诸如AES的强加密算法。 The harder question is "AES requires a secure key. What do you do with the key?" 更难的问题是“AES需要一个安全的密钥。你用钥匙做什么?”

Google recently announced a cloud-based storage solution for apps, so you could consider storing the key there if the situation allows. 谷歌最近发布了针对应用程序的基于云的存储解决方案,因此如果情况允许,您可以考虑将密钥存储在那里。 Otherwise, its seems that getting the key outside the device, like on a server, is better. 否则,它似乎在服务器之外获取密钥更好。 If you can make the user punch in a PIN, that would actually work the best. 如果您可以让用户打入PIN,那实际上效果最好。 You can do password derivation in order to store the password, and you can redo the derivation to verify the password 您可以进行密码派生以存储密码,您可以重做派生以验证密码

Without the "user punching in a PIN" part, I haven't found a lot of good answers to that question. 没有“用户在PIN中打孔”部分,我没有找到很多这个问题的好答案。 However, DO NOT HARD-CODE THE KEY IF YOU MUST STORE ONE WITH THE APP. 但是,如果您必须使用APP存储一个,请不要使用密钥。 At the minimum, generate a key using a secure password generator and/or a derivation function like PBKDF2 (Password-based derivation function 2). 至少,使用安全密码生成器和/或类似PBKDF2(基于密码的派生函数2)的派生函数生成密钥。

If I read the posts correctly, Google did say that one approach is to generate a key once the app starts the first time, store the key via the MODE_PRIVATE flag to a lot of file I/O operations, and use that as the key. 如果我正确阅读帖子,谷歌确实说过一种方法是在应用程序第一次启动时生成密钥,通过MODE_PRIVATE标志将密钥存储到许多文件I / O操作中,并将其用作密钥。 You can also derive other keys based on that master key, and the NIST actually suggests something along that lines. 您还可以基于该主密钥导出其他密钥,而NIST实际上也会根据这些内容提出建议。

Whether or not to trust the master-key method, I'll leave to you. 无论是否信任主密钥方法,我都会留给您。 This key would get exposed on a rooted device. 此密钥将在root设备上公开。 I'll also admit that I'm still researching the issue 我也承认我还在研究这个问题

Every application on Android runs in a secure sandbox environment, so other processes on the system cannot access your code or private data without proper handshake. Android上的每个应用程序都在安全的沙箱环境中运行,因此如果没有正确的握手,系统上的其他进程将无法访问您的代码或私有数据。 But still there are many vulnerabilities are possible by poor design of the apps. 但是,由于应用程序设计不佳,仍然存在许多漏洞。 This link from Android developers site advice you some of the good tips for security - https://developer.android.com/training/articles/security-tips.html 来自Android开发者网站的链接建议您提供一些安全性方面的好建议 - https://developer.android.com/training/articles/security-tips.html

If you want to pretty much ensure the user cannot see the data other than by looking at your app then encryption is really the only way. 如果您想要确保用户除了查看您的应用程序之外无法查看数据,那么加密确实是唯一的方法。 Even the "protected" storage is accessible to the user if a device is rooted. 如果设备已植根,则用户甚至可以访问“受保护”存储。 Even encryption is not totally secure as you need to decrypt the data at some point in order to display it. 即使加密也不是完全安全的,因为您需要在某个时刻解密数据才能显示它。 You will dissuade the casual browser but not the determined hacker. 你会劝阻休闲浏览器,但不会劝阻黑客。

Use SSL on HTTPS to transfer data instead of HTTP you need to setup the certificates on the webserver not very sure how it works.. 在HTTPS上使用SSL来传输数据而不是HTTP,您需要在Web服务器上设置证书,而不是非常确定它是如何工作的。

If you are really concerned about the data then further encrypt it with a unique algorithm before sending and decrypt it when it reaches the app. 如果您真的关心数据,那么在发送数据之前,请使用独特的算法对其进行进一步加密,然后在到达应用程序时对其进行解密。 I guess that's all about it.. Unless you need something really strong then develop your own protocol based on TCP and/or use another port.. maybe that'll help 我想这就是它的全部......除非你需要一些非常强大的东西,然后根据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/ 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-证书/

As for storing data in the app what you can encrypt the data before storing or you can use another format other than SQLite for better security as you can view sqlite databases using the browser pretty easily. 至于在应用程序中存储数据,您可以在存储之前加密数据,或者您可以使用除SQLite之外的其他格式以提高安全性,因为您可以非常轻松地使用浏览器查看sqlite数据库。

Unless the phone is rooted there should not be a way to extract the data from it. 除非电话根植,否则不应该从中提取数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM