I’d like to store a key->value structure of data e.g.
2354235 => string1
3453453 => string2
The structure has to be defined at build time and not modifiable over the runtime (security reasons). It must be stored securely (readable only by the app). Storing that in source code and in sqlite db are not acceptable. Any other ideas?
You are asking two things:
1) Where can you store that at build time, outside of code or DB.
2) How can you make it only readable by the app.
For 1), I suggest you just use an encrypted raw file (place it in /res/raw). They cannot be modified, and it could be just CSV or JSON. Check the javax.crypto package for the necessary classes for encription.
For 2), it depends on how secure you want it to be. You could download the decryption key from a server using a secure connection, but then you need to be sure that what's connecting to the server is really your app. You can use something like what's described here for validating your app in the server:
Summary
Doing this is a multi-step process, which I’ll outline in full, but here’s the short version: You use the GoogleAuthUtil class, available through Google Play services, to retrieve a string called an “ID Token”. You send the token to your back end and your back end can use it to quickly and cheaply verify which app sent it and who was using the app.
Related
I am building an app which generates a random password and you can keep it along with your other details such as username, website url, name etc.
Basically a password management thing.
Things to be stored:
When I am clicking on the save button, I wanted it to be saved somewhere locally. So that, I could retrieve them and display it in another activity.
Can I share those things in SharedPreferences for all those password entries securely? [By password entry, I meant the entire class ]
I have referred to something like ComplexPreferences [ http://blog.nkdroidsolutions.com/class-object-in-sharedpreferences/ ]
I've tried them because I had created a class containing all these data [title, url, username, password, notes]. But I cannot retrieve them properly using a recyclerview. I'm ending up with some error.
If it cannot be done with SharedPreferences, how can I do it with SQLite Database?
But how can I save them securely? I don't know much about security in Android.
Please guide.
The shared preferences and sqlite db both are secure for an extend only.
It can be easily accessanle and can be modified even there are several apps available to edit the shared preferences and sqlite db in playstore . **
So i prefer not to store it locally
.you can use some kind of **algorithms and mechanisms to encrypt and decrypt the data that you are going to store locally.
if the device is rooted then its a SERIOUS ISSUE
Let's say, that you have a generated password along with other details like user name. Storing this kind of data is a perfect fit for SQLite. But, storing in plain text is not safe. Either the whole database or individual records should be encrypted. The former can be done using one of the open source database encryption libraries. For the later you have a couple of options:
Ask the user for a password each time he opens the app. Generate the actual encryption key using password-based encryption and the same salt value.
You can use the Android Keystore Provider to generate an encryption key and save it for you in a safe location on the device. Later, you retrieve the entry from the keystore and use it to encrypt/decrypt your database records using javax.crypto.Cipher.
Both options ensure that the encryption key is not be present in the app.
I still don't understand, why you need to save it locally? If only your application will be able to unlock data. In this case, only your application will have keys to working with this files.
For this example, you can easily work with SharedPreference with Private Mode. Furthermore, it's enough for most tasks. We using this option to save User's token, and it's Ok, for system. (If we talk about safety of this way, so you will have some risk for custom ROM, for Users, which manually flashed on device.)
If you need more complicated things, you can use sample, for using Android Keystore, with generating Key Pair, and saving data. For example you can check this source.
UPDATE!
So question was updated a lot, from first version. I will update information what you a looking for. Saving huge encrypted information locally.
Maybe easer way to do it, it's just use local encryption of data, as I described above, using Android KeyStore, KeyChain (links above). You will create our own KeyPair and will use for encryption and descryption some data. But this data, you will save in your DB in encrypted view.
Another more complex solution, will be creation of mechansim for encyption/decryption DB. As you described, you will save all information in DB, and after, just encrypt/decrypt you DB files. Fortunatly, we already have such library SQLCipher, just take a look. Fore example, this is pretty simple tutorial
We have an Android application which stores its data in a local SQLite database; primarily for performance, but also to allow for working off-line (as we are often in areas with low signal).
At the moment, the data is stored in encrypted format (passed down from our web servers), but this in itself causes a performance issue, where for example, if we want to search records for a particular "surname", we need to decrypt ALL of the data, rather than using a straight SQL query, to include where surname='Smith'
We cannot (as it currently stands) store the data in a more friendly 'open-format', as it's possible to 'root' the device, take a copy of the MySQL database, open it and read the data.
Is there the means (perhaps someone can provide an example) to either password protect the local SQLite database or somehow apply encryption, so that we can (from an application perspective) have the database available in open format, but so that if any would-be hacker got hold of the device and rooted it ... they would have a hard time reading our data?
I have searched for a suitable solution and cannot find any options for the SQLite database, any 3rd party software or any examples of code that do this.
SqlCipher, this will might work in your case
Remote Storage:
Your data is sensitive and needs to be accessed by the user on the go from different devices. If your app is a good one then the above line will hold true.
Security + Remote access from any device says you maintain your dB on a remote server.
Your flow can be :
User login --> Token --> Auth Token in every call --> Process request and get/put data in/from dB
Local Storage:
Let's say that you only want to store data locally and don't want to store it on the server. For this you can use public-key cryptography
You can use a public Key in your app to encrypt the data and store it. Now, you want to access the data. Request the private key from the server and decrypt it.
Again, to get access to private key you should use some form of authorization (or anyone can access your key).
Without the private key, even if a hacker roots the phone and gets his/her hands on the dB, the data would be useless.
I saw similar questions but they don't fulfill my requirements.
I have an app that time to time needs to be updated from a web service. Data contains such fields as url, description, title. from 200k to 400k entries.
It is used locally and search among this data is performed quite often (depending on user's activity).
Data shouldn't be accessible by users and search needs to be as quick as possible. I know that there is no way to make it 100% unreadable, everything can be reverse-engineered and decrypted (I have to keep the encryption key on a phone). My goal is to make it as difficult as possible.
I have few choices:
1. encrypt data on server and send it as binary file to phone. Decrypt it every when needed
2. also send data as file. Read it, store to local database
3. Get it as JSON (probably encrypted), store to database or file
There is an advantage of using JSON because it will be easier to implement updates of difference between local data and remote.
Also there is a question about databases. Should I store all entries encrypted and decrypt it every time I want to find something? It might affect phone's performance.
There is also one more possible layer of protection - make encryption keys dynamic. Get a key from server once a day, re-encrypt stored data, the next day key changes. However I suppose it is an overhead. Tell me if it isn't.
What option would you choose? Are there any better solutions?
P.S. database is going to be updated daily.
Thanks
I'd store the data in SQLite, but also make the decryption scheme more intricate, using at least two keys... one, stored in the shared lib, other downloaded from the service and unlocked with that key.
This also plays into your thought up strategy - you can have one 'device' key, which comes with the APK - embedded as a hardcoded byte[] in the .SO, and another 'daily' key which will be used to open 'daily' data updates. Although, i'd rather be using the 'daily' key in a bytearray format, never saving it in any form on the device except having it decrypted in memory only for duration of it's use. This would be an upgrade to what I did, where i just saved that key as a base64-encoded devicekey-crypted string.
Working with SQLite is fairly easy, which you can see here - Android Database to Array.
I did something similar to what i'm explaining (without the updating daily keys however) here - not decrypting what I crypted.
Give it a look and discuss :)
What would be the best most secure way to handle confidential text in an Android app?
The basic structure is (text/int) and some similar variations of it.
The app only shows a selection of the (readable text /readable int) at a time, so decryption will only be done for very few pairs at a time.
I need to make sure that extracting the complete (text/int) information is practically impossible - if possible :-)
Is there any standard library/scheme to handle this?
Many thanks
EDIT (after getting some very interesting responses to this question):
It seems that even when the data is encrypted one could easily take the de-compiled code from the app, combine this with a self-written extraction routine, and hereby get all the decrypted info to a file. Since the encryption key has to be provided to users of the app, everybody could potentially get to the data this way.
So in summary there is no real good solution?
You can save your text/int pair into the SharedPreference.
Because it's not secure, you can encryt the data before saving it into the SharedPreference in the same way as Google do in the Application Licensing package.
More details can be found in the Implementing an Obfuscator part.
The code source of the AESObfuscator can be found in the SDK in the market_licensing/library/src/com/android/vending/licensing folder.
I think in your application you can use a symmetric cryptography and you can store your key in the Keystore. This key should be protected with password. Every time, when you run your application, it will ask the user for the password. If the password is correct then the key is extracted from the Keystore and used to decrypt your data. In this case, there is no difference where you store your data (text/int pairs) because all data will be encrypted. For Android SDK look at the package java.security and to the class java.security.KeyStore
If you want to supply your application with the data that you don't want to be extracted then obfuscation is a possible solution if you write in Java. If you want this functionality to be written in C/C++ then use Android NDK.
I've got an app that can save stuff you like to Google Storage for Developers. Assuming, of course, that you have an account and associated access keys. Their web based key management tool allows you to create keys and associated secrets. My question is regarding how a user can most easily install these in their copy of my app, allowing them to use the cloud storage.
A key is a 20 character alphanumeric string, and an associated secret is a 40 character Base-64 encoded string. It is clearly impractical for the user to enter these manually. Cut and paste across activities seems way awkward to me. How do you suggest getting two strings from a web page to two activity EditText fields - or to a tmp file I can read and then dispose - or ??
thanks.
The best way to go about it would be the API from Google
If you have access to a web page, there are these values are residing, you can download it, parse, and get these values.
Since it doesn't look like Google provides an API specifically for getting keys, your best bet would probably be to use an HTTP GET to pull the web page containing the keys and secret keys.
If you need to be authenticated with Google to do this (presumably you'd have to be), you could use SignPost to handle OAuth and make secure HTTP requests. After you pull the page, parse through the HttpResponse content and store the keys in a text file or a SharedPreferences file.