1

Problem: I need to store a SECRET key (String) locally on the device. How do i reasonably do this?

It is impossible to keep something 100% securely private that is stored locally but I want to make it as difficult as possible for someone to extract the secret key. What are my options?

Requirements

  • There should be no UI operations involved.
  • The secret key should not be extractable in an trivial way.

Possible solutions

evanill80
  • 157
  • 2
  • 11
  • 3
    You can't. You can at absolute best get some security through obscurity. If the key is on the device, whoever has control of the device can and will get it if they want to. You're wasting your time even worrying about it- if the info is really secret, don't store it locally. If it isn't, then just count on private directories to keep it secure from other apps and stop being paranoid. If the user is concerned he can put a password on the device. – Gabe Sechan Jan 27 '16 at 22:13

4 Answers4

2

You can now use a new gradle plugin + library to effectively obfuscate Strings in a class, Please check it here

https://github.com/MichaelRocks/paranoid

Also now there is a new plugin which can obfuscate resources also, please check it below

https://github.com/shwenzhang/AndResGuard

And help share and upvote this great information, so more developers can use it and thus more and more developers will contribute for further development of these plugins, and thus we can collectively improve these plugins and will give a nightmare for crackers.

Vaishakh
  • 1,126
  • 10
  • 10
  • I tried paranoid and marked @obfuscate for few activities, resulting apk de-compiled with JADx and the strings were still visible. is something wrong? – NBaua Sep 06 '18 at 10:51
  • do you added gradle dependency, and marked @Obfuscate , 'capital O' – Vaishakh Nov 14 '18 at 07:02
0

You can put a layer of encryption over your SharedPreferences and store any secret key(s) there itself.

I used these as references in one of my apps and should be helpful in your case too.

First link: http://right-handed-monkey.blogspot.com/2014/04/obscured-shared-preferences-for-android.html

Second link: What is the most appropriate way to store user settings in Android application

Community
  • 1
  • 1
Alucard
  • 37
  • 1
  • 4
  • 2
    Wouldn't a key be necessary to decrypt and access the SharedPreferences? If that's the case I would need to store that key which would put me back where I started. – evanill80 Jan 27 '16 at 22:23
0

With no UI interaction involved, the best you can do is encrypting all the data with a key you will have hardcoded in your app (or using a certificate whose passphrase you will have hardcoded in your app).

The only thing you can do then is try to obscure that key.

You can obfuscate Java code using ProGuard or similar things, but that will still be really easy to inspect and the key will be easily extracted.

In order to obfuscate the code a bit more, you can insert your key in C code and encrypt/decrypt through your own JNI interfaces. That will give you the best you can get right now.

Mikel Pascual
  • 2,202
  • 18
  • 27
0

Everything you may try will fail if the attacker can download you APK, make it debuggable (this implies re-signing it), and hack it using ADB. Whatever obfuscation you use, you are likely to pass the key to a framework API somehow, and this is where the attacker will be watching. If you need to keep a secret, use AndroidKeyStore to generate it, this way the secret won't be extractible (unless is not hardware backed). Basically your opponent could have complete control over their rooted phone, a soon as you ship the secret with the APK, that secret is lost.

One solution : create a wrapping key pair in hardware-backed Android KeyStore, generate a key attestation, get your backend to verify the key attestation, encrypt your secret, and send it to the device in wrapped form.

This, unfortunately, will only work on Android P devices.

Toluene
  • 751
  • 3
  • 9