7

I have an mcrypt encryption and decryption routine within one of my Android apps. This is essentially decrypting a string which is fetched via. remote call. Naturally the "secret key" is stored within the code, but anyone with apktool can obviously see the code and see my secret key.

Is there anyway to encrypt all the Java code so that even if de-compiled it would not be readable/understandable?

I've heard of ProGuard, but from reading about it, doesn't seem sufficient for this purpose.

OmniCoder
  • 117
  • 1
  • 8
  • 2
    The question is why the string is encrypted? If it is for transport and server storage security then use public key encryption. If you want to "hide" it from the users then you're out of luck since everything your application can "see" so can the users. – Sani Huttunen Oct 31 '11 at 09:44
  • The string is encrypted to hide the location of a file which is streamed - the intention is to obfuscate and at least make it more difficult for casual users/script kiddies from downloading the mp3 independently of the app. I know what your saying and completely understand that anything the app can see - anyone determined enough could debug, decrypt or decompile - I'm just trying to make it more difficult. Someone determined will still go through all that and succeed. No biggie.. just keep out the script kiddies basically.. – OmniCoder Oct 31 '11 at 09:49
  • 2
    Why not have the client generate the key pair and send its public key to the server with the request? – Nathan MacInnes Oct 31 '11 at 09:49
  • @Nathan Good idea, creating a random key on the client. Plus: The secret key may be stored in an SQLite DB or in some other form in application-private storage. This should prevent access from outside your app - at least on non-rooted devices. – JimmyB Oct 31 '11 at 10:12
  • @HannoBinder, yes or one could generate the key on the fly, depending on the complexity required. – Nathan MacInnes Oct 31 '11 at 11:43

4 Answers4

4

You should never put a secret key inside code. Compiled code can be easily reverse-engineered and anyone with a debugger can hook to the point where the actual key is created. Security always relies on the algorithm, it is assumed that the client code is public and a potential attacker has a copy.

Hiding literals in code just delays the attacker in the process of getting the key, but it doesn't prevent it in any way.

Mister Smith
  • 27,417
  • 21
  • 110
  • 193
  • So, what are your recommendations? – OmniCoder Oct 31 '11 at 10:57
  • There could be a config screen so that the user is able to define its own psw. Then you store a hash of the usr pasw, and when the app launches, the psw is requested. If the psw hash matches the stored hash, then you grant access to the user. You can also issue keys to users, store hashes in your DB, and let them validate their app on first use online. – Mister Smith Oct 31 '11 at 11:13
1

All code on the client machine can be read. The best you can do is to make it more difficult to find the key.

A suggestion: there will be some text strings in your code, like "Please wait while your request is processing..." Find such a message, and generate a byte array to change that message into your real key by XORing the byte array with the text string.

e.g. "squirrel" XOR [16 1D 10 19 1A 13 0B 18] => "elephant"

Only "squirrel" and the byte array actually appear in your code.

rossum
  • 15,344
  • 1
  • 24
  • 38
  • Hi! Yes this is along the lines of what I was originally thinking. Essentially having a few routines (utilizing algorithms) which creates the key out of data within string.xml and also some other randomly embedded variables. Combining all this into several methods embedded in separate classes. Then finally using ProGuard which would make tracing what specific functions/routines are doing more challenging.. – OmniCoder Oct 31 '11 at 10:01
  • I know someone could still figure it out even in that instance, but it's a tad more time consuming - taking it from simply decompiling and reading, to having to trace through the code for a few mins. – OmniCoder Oct 31 '11 at 10:02
0

I am not a security expert nor, but I do know that VM compiled language can be easly decompile you can try to obfuscate your code using ProGuard but still be readable, what i would advice it's try to save it and crypt your key using Java Crypto, this kind of question have been asked before similar to Android Crypting Database or Encrypt Information in Android, I don't expect to answered your question but give you a guide line where to go from now.

Community
  • 1
  • 1
Necronet
  • 6,704
  • 9
  • 49
  • 89
  • Thank you Necronet. I've read several posts on here without a definitive solution.. I will check the ones you linked. – OmniCoder Oct 31 '11 at 09:51
0

you can instead generate a new key each time you need fetch the string

you'll then need to do a key exchange with a hardcoded certificate (which is secure if properly implemented)

or just use SSL if it's only to secure while in transit

ratchet freak
  • 47,288
  • 5
  • 68
  • 106
  • 1
    This approach sounds plausible.. generating a new key each time is doable, but I'm not familiar with key exchange with a hardcoded certificate. Could you elaborate further or point me in a direction? I' – OmniCoder Oct 31 '11 at 09:57