Android and Java provide a crypto API that is relatively easy to use for crypto non-experts.
But since we know that no code can really be protected from reverse engineering, especially string constants used as seeds or shared secrets, I am wondering: What is the point of going through the ordeal of encrypting and decrypting in Android applications?
Am I missing something?
Trying to make my question clearer and more concrete: Suppose I have an application in which certain strings used by the code and in the code (i.e. not user data) need to be secret: One approach is to store them in encrypted form in the compiled .apk and decrypt them (using an obfuscated hard-coded password) at runtime. Another approach would be to store them in encrypted form in a remote server, fetch them (over the Internet) and decrypt (using a shared password) them at runtime.
I don’t see much difference between the two, since both require the “secret key” being present in the (reverse-engineer-able) code.
Is there a solution to this problem?
If there isn’t a solution, why encrypt at all?
This is not strictly a problem with Android or Java. Anything can be reversed, it’s just harder if it’s native code. And bear in mind that they don’t even have to reverse it: you have to eventually decrypt the data on memory to manipulate it. At this point, the attacker can just take a memory dump and they will get your data. If they have physical access to the device, and you are manipulating the data in software, there is really nothing you can do to stop them. The solution for this is to use a dedicated hardware module (HSM) that is tamper-resistant or at least tamper-evident (if some one messes with it, it either deletes all data or at least keeps some logs of the event). Those come in different shapes and sizes ranging from smart cards to network connected devices that cost a lot. Currently not available for Android, but maybe it will get something similar to a TPM, so you can store your keys securely and do crypto operations in hardware.
So consider just how secret your data needs to be and decide on an adequate protection level.
You might want to have it downloaded it over SSL (that would protect it in transit), making sure you authenticate both the server (so you know you re getting the right data from a trusted place) and the client (so you can be sure you are only giving the data to the right person). You can use SSL client authentication for this, and it will be much more secure than any custom encryption/key exchange scheme you (or anyone who is not a cryptography expert) might come with.