I'm creating an application that encrypts data with a key that is created each time the user logs into the app. However, there are times when data will be received via a BroadcastReceiver that needs encrypting, but the user is not logged in and so the encryption key is not available.
Security is pretty important and so using a key stored in code to encrypt the data until the user next logs in is out of the question as is storing one in the applications DB despite it being within the apps sandbox.
I've been searching through the Android docs and get hints of APIs to address this situation but have not yet come up with a definitive solution.
Anyone know of the usual solution to this problem? I expect it crops up quite a lot in software development.
Let's see...
Setup: Create an RSA keypair. Encrypt the private key. Store the public key unencrypted.
Broadcast received: Generate a random AES-128 key/IV. Encrypt the key with the RSA public key. Encrypt the payoad with the key/iv. Store the encrypted key, iv, and encrypted payload.
Login: Decrypt the private key. Use the private key to decrypt the AES key. Use the AES key to decrypt the payload.
And since this was the first idea that came to mind, I can't vouch for its security properties.
I'm also not sure what security properties you're looking for — what attacks are you attempting to defend against? Why couldn't an attacker just intercept the broadcast directly? Aren't you worried about it lingering around in other processes' memory?
Two ideas:
The BroadcastReceiver get the encrypted data, do the login by stored credentials and get the key to decrypt the data.
You BR just store the encrypted data and inform the user, so the user logs in to get the decrypted data.
I don't know what your app does, so its just a guess what could be possible...
Related
I want to send sensitive data from one app to another.
I use Intent and send data via Bundle. Now, I am supposed to use an encryption algorithm to encrypt the data to send and parallelly the receiver app will decrypt the data.
Which algorithm is best suited for the mobile platform?
I have gone through RSA documents suggests that it is not suggested for long text encryption.
I have seen the algorithm uses a random key generation method which will cause an issue in my case as both the app need to share the same key to encrypt and decrypt.
I have gone through RSA documents suggests that it is not suggested for long text encryption.
true
Depending in the key length, e. g. 2048 key with pkcs#1.5 padding is intended to encrypt maximum if 245 bytes. Some implementation frameworks enforce even less (144 bytes,..)
I have seen the algorithm uses a random key generation method which will cause an issue in my case as both the app need to share the same key to encrypt and decrypt.
Actually - it's a combination of the both ways what is commonly used. see hybrid cryptosystem
Basically - each app has its own keypair and the apps share the public keys of the destination parties. You can use a random key for data encryption and rsa to encrypt the data key. Then feel safe to use Intend and Bundle to move the encrypted data and encrypted key.
It may be a good baseline to start with.
Edit:
I need to send data from my one app(A) to another(B). So, A will encrypt the data and will send the data to B with encryption (key is generated in app A).
If you send an encryption key (let's call it data key) along data in plain, anyone intercepting the traffic (intent or bundle) would be able to decrypt the data. So that's where the RSA comes into the game. You can encrypt the data key the way only B can decrypt it
Now B has to decrypt the data. If the new code of key generation will be written in app B then it will create different key and hence will not be able to decrypt....
Try to search and learn how an asymmetric cipher (RSA) works. The full description is outside scope of the question, you may ask another one what is not clear in it.
Basically - app B needs to create a keypair (public and private key). The public key is used for encryption, the private key is for decryption. A needs to get the public key of B to encrypt the data key.
How you get the public key from B to A is up to you (shared storage, configure in an app, ..)
You want to pass encrypted data without sharing a common secret between apps, then RSA is a way to go.
I need some string values in my app that I don't want to hard code (one of those in the public key for network communication). So I made a encrypted version using AES algorithm. Now whenever I need the original stringm I need to use my key for decryption, so where should I store this key? It doesn't seem logical to store it as an hard coded string, and I don't want to store my key on the server. What should I do?
You can use JCA. Use its Password-Based Encryption.
This way you do not have to store your key any where.
Whenever you need to decrypt the data, type your password and you are good to go.
http://docs.oracle.com/javase/7/docs/technotes/guides/security/crypto/CryptoSpec.html#PBEEx
Note: The same salt and iteration count that are used for encryption must be used for decryption.
A good way to encrypt and decrypt stuff in your app without hardcoding pwds in the code is using PIN protection screen on the app. Doing this you can derive a final key to encrypt sensitive data and with the same key decrypt everything. Hope this idea will help you to figure out what do you have to do.
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
I'm creating an Android application, that at first needed to be able to transmit data to the server securely. So I thought of RSA.
I would send the public key to the user, let him do what he must, then receive back and decrypt via private. That is all fine.
But now it seems, that there should also be some sort of encryption to the other side. Meaning, there should be means of encrypting a message and sending it to the user, and allow only the specific user be able to read it.
This smells like having 2 pairs of keys, and sending public key from one pair and private key from the other to the user, and keeping the rest to the server.
I have looked at symmetric keys, but they somehow seem less secure to me.
Am I missing something, or is this common? I'm somewhat new to the whole cryptography scene.
The usual advice applies: use HTTPS, don't try to invent a secure messaging protocol. You will most likely fail. If you absolutely need to this, the usual way is to use RSA keys to encrypt symmetric session keys and encrypt your data with those. Also note that the size of data you can encrypt with an RSA key is limited by the key size (1024, 2048, etc. bits).For two way communication, each party needs to have the other party's public key. So it goes something like this:
Alice hands her public key (RSA) securely to Bob (see below)
Bob hand his public key (RSA) securely to Alice
When Bob wants to communicate with Alice, he generates a session key (say, a 256-bit AES key), then uses her public key to encrypt it.
Bob sends the encrypted session key to Alice.
Bob uses the session key (AES) to encrypt the message, and sends it to Alice.
Alice uses her private key (RSA) to decrypt the session key (AES).
Alice decrypts the message from Bob using the session key (AES).
Reverse the roles of Alice in Bob in steps 3 to 7 for communicating the other way.
But of course, if you send a public key to someone, how can they be sure that it is actually your key, not mine? If you don't hand it in person and show your photo ID, this is far from trivial.
Then, you need some way to verify that the (encrypted) message from Bob has not been modified (you can cut in half, and it will still be valid and decryptable; there are other, more sophisticated attacks, of course).
So just convince whoever you need to convince to use HTTPS or some other established protocol, and don't try to re-invent the wheel.
This smells like having 2 pairs of keys, and sending public key from one pair and private key from the other to the user, and keeping the rest to the server.
This is not how public key infrastructure works. Each of you generate your own keypairs, and exchange public keys.
Server's public key is used by client to encrypt data to server and verify signatures on messages received from server.
Server's private key is used by the server to decrypt messages from the client and to sign messages going to the client.
The reverse actions for the client's keypair are the same.
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.