I don't understand what the hacker can see and cannot see when he enters in a mobile app, for example android. He decompiles the .apk, then sees some .class files. If for example, I encrypt a key/value pair in a file, I still need to call this key from the code, and if the hacker can see the code, no matter if the key is encrypted, he will know which key I am calling?
My goal is to keep some encrypted string in my app, for example the twitter account Id of my app.
Some topics talk about " a private key to read, what was encrypted with a public key ", but if I use them, I still need to store them somewhere in my app...
Don't completely understand your requirement but the rule-of-thumb is always assume that client is not to be trusted.
You have to ensure that
All decryption should be done in your server (which you trust).
The client should never be able to access the decrypted data (unless you want it to). Hence whatever part of your code that needs to directly access the decrypted data should be in the server.
The client should have only the encrypted data (if it must store data).
The client should not be able to access the private key you used to encrypt the data.
If in your case your client must be able to access the critical data directly, then your only resort is to use obfuscation techniques (Basically hiding your data/code, to make it hard to find/understand). Of course all obfuscation techniques can be defeated eventually by a determined hacker. You have to decide how valuable your data is, what are the probabilities a hacker will try and access your data.
To take an extreme example : storing your twitter account and password using obfusucation is very bad. Storing a twitter-url- might not be so bad.
you can get your keys from server while launching app. and also dont manage in app purchase detail in sharedPrefrence or Sqlite. because in rooted device user can see that data file from root browser or sqlite editor application so user be able to change value.
A very determined person can crack it, but it's a major pain to crack encrypted strings and will stop most hackers. Especially if you obfuscate your code with something like ProGuard.
Answer to a similar question for details on how to encrypt
Related
I'm trying understand which is the best way to store sensitive data in Android. In my app i want to insert a classic in-app-purchase model with some coins. My problem is that i'm not sure how to implement this correctly.
The initial idea was to simply use my firebase database, store the number of coins for every user and fetch the data every time the app is launched. This way I can easily detect some inappropriate usage but my users are forced to use the internet to play.
Looking at the documentations, I found this. Can this be a solution? Can I save in the internal storage the number of coins, maybe with some type of encryption, to avoid root user to modify the file? Then when the internet is on I can double-check the local stored variable with the the one in the database.
Thanks
Not an "easy" task.
Technically, you can create a SecretKey and encrypt data, so no normal user will be able to reproduce. If your concern are root users, You are kind of out of luck, as he can hook into your app while it is reading/writing that value.
But to store it online is not a solution in itself. You have to answer questions like: "Do you trust any server input"?
"How to make sure just paid coins are added"?
Have you had a look at Google Play billing?
it provides safe way's to determine if somebody paid or not.
This will require to be online.
If you have a sensitive data to save you can use sqlcipher database .. the good with it that it encrypt the database file itself so even the root user be able to get the database file he will not be able to decrypt it if you use a secured encryption algorithm.
you can find more about sqlcipher here
https://www.zetetic.net/sqlcipher/sqlcipher-for-android/
Since I assume you will grant your app a reading permission of your sensitive data and all writing processes should be reserved server-side, I would not recommend storing the data in a file on a phone, though every encryption can potentially be passed.
Maybe you already have heard about SharedPreferences, which is a good solution for let's say Preferences the user selects and that only shall affect his particular installation of your app. The difference is, that values are not stored in an external file, so not that easy accessible, BUT your app needs to write them, due only the app can access them directly (also your server can't). I am not aware of how your sensitive data is used at all but I would also not use SharedPreferences since it's injective-prone.
Official docs about SharedPreferences.
If security of your data (speaking of Confidentiality, Integrity, Authentication) is your No. 1 priority, simply don't store your sensitive data on the users device. Focus more on creating an API that ensures secure and performant passing of the relevant bits of your sensitive data. Hope this helps to give you a view of which way to go and which to walk around.
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
I need to store sensitive data in a sqlite database in an android app.
How can I be sure this data is very safe?
I know I can encrypt the data using a key, but where do I store that key? I don't want to ask the user to fill in a key either, I just want it to work on it's own.
Because I am afraid of reverse engineering I don't want to put an encryption key in the code either.
I found out about SQLCipher. It says it's a very secure way of encrypting the data in the database, but why is it that way? Don't I also need to keep a key to unlock that information? Or is this really a perfect way of making sure the data is safe?
And if it isn't, what is an (almost) fail-proof way of storing sensitive data in an sqlite database?
You said...
I don't want to ask the user to fill in a key either, I just want it
to work on it's own. Because I am afraid of reverse engineering I
don't want to put an encryption key in the code either.
Unfortunately, you need to do one of these things (well, probably). You can ask the user for a password and then derive a key from that using an algorithm designed for that purpose (that's known as Password Based Encryption - PBE - and Android includes some good PBE algorithms standard). You could store the key in your code or as a resource within your APK, but then someone would be able to reverse engineer it. You can do so and obfuscate your code, which will slow down the reverse engineering process, but you cannot make it impossible (your code will need to determine the key at some point so it's just a matter of an attacker figuring out how it is doing it).
Other approaches that have been tried here include forcing your client to connect back to a server to retrieve the key over the network...but then what happens if network connectivity is interrupted and what prevents the server from giving the key out to anyone, like an attacker? Well, then you could use mutually-authenticated SSL to ensure only your client is allowed to get it...but then you need to store the client-side SSL private key...which is exactly the same problem you have now. :)
So...the bottom line is that you need a key (or something equivalent) to encrypt/decrypt the data. You can store it and make it harder for someone to reverse engineer it. You can inconvenience the user and make them type in a password. But...you need that secret knowledge somehow.
Symmetric cryptography requires a key to encrypt and the same key to decrypt. There is no way around it.
Do not store the key in the code because it can be decompiled (Like you've said).
Ask the user for a password on the first use and use PBKDF2 to derive a cryptographically secure key to use in the encryption.
Either the user has to enter the password or you need to store it in the memory. What I'd do is, ask the user to specify a duration where the key will be cached in the memory to use for decryption.
And if the duration is expired, the user WILL have to enter the password again.
I didn't check SQLCipher thoroughly but it says it uses AES-256. AES is a symmetric cryptographic algorithm and it needs a key to encrypt and the same key to decrypt.
Is it possible to let apps auto gen a random password? May be gen from place,time or others information this will no need to ask user's pass.
I have an Android application and within it some strings which I send through htpps. Is it possible to encrypt those hardcoded strings (such as for example passwords) in Android application to be unreadable from the apk file?
Regards,
So if I understand your question correctly, you want to store encrypted strings within the Android apk file (in strings.xml for example). If this is the case, yes, you can absolutely store encrypted strings wherever you please.
The kicker is that in order to decrypt these strings, you'll need a key. Wherever you end up storing the key becomes the weak link in this chain. If your app is reverse engineered and someone gets a hold of the key, your strings are no longer encrypted.
So to answer your question, no, it's not possible to do what want.
Check out What is the most appropriate way to store user settings in Android application and a whole bunch of other question. Basically you can obfuscate and encrypt to some extend but you will never be completely safe on a rooted device and against network sniffing attacks. That said though that applies everywhere.. find your best compromise between level of effort to implement and crack and the data you are protecting.
I think you should explain what do you want to do with this strings.
If you want just send password to server and make some kind of authorization, you can use MD5 or some other hash function to hide thode values. Hashed password can be compared with hashed password at the server side.
If you want to send encrypted text and decrypt it at the receiver side then you have to use some encryption algorithm, e.g. DES (some kind of encrypting key will be needed).
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.