7

I know that a public client shouldn't use a client secret because, no matter how much you obfuscate it, it won't be protected from reverse engineering.

But, the people in charge of the service I am authenticating to don't want to/can't change it. So, I need to store the client secret and try to protect it from reverse engineering as much as I can.

So, I thought of encrypting it using at build time using gradle and store it in a file. Then, when I need it at run time I decrypt it. But now I have to solve the problem of how to store the encryption key...

I don't know much about security, so, I don't know if this can be solved, or if Android (min sdk 15) provides any mechanism for this kind of scenarios.

Any idea?

Community
  • 1
  • 1
pomber
  • 19,363
  • 9
  • 71
  • 90
  • 1
    possible duplicate of [Best Practice for storing private API keys in Android](http://stackoverflow.com/questions/14570989/best-practice-for-storing-private-api-keys-in-android) – Duncan Jones Feb 23 '15 at 09:10
  • 1
    Possible duplicate of [OAuth secrets in mobile apps](http://stackoverflow.com/questions/1934187/oauth-secrets-in-mobile-apps) – Damian Yerrick Aug 01 '16 at 16:25

5 Answers5

4

This article suggests these options, from less to more secure:

  1. Store in cleartext

  2. Store encrypted using a symmetric key

  3. Using the Android Keystore

  4. Store encrypted using asymmetric keys

Probably, using a combination of #4 and some way to univocally identify the device would be secure enough

jmm
  • 984
  • 11
  • 35
2

Maybe the best option is to use NDK because it can not be decompiled, like Godfrey Nolan points here

Here is a resource I found useful that helped me to implement it link to the resource

Cheers

agusgambina
  • 5,073
  • 14
  • 46
  • 77
  • 2
    Just because it can't be decompiled doesn't mean it can't be inspected: native code can be disassembled into assembly instructions close to those generated by the compiler. It is more difficult to read than high-level code but it is code nevertheless. – mijiturka Jun 13 '17 at 10:40
1

As you said, whatever you do, how much you try to hide your key, you can not hide it 100%. But, if you want to make reverse engineer's work harder;

Firstly obfuscate your client (I guess you already do).

Secondly, do not put your key into the client hard-coded. Receive the key after login or user opened the application. And deliver secret key to the client over SSL. Store the secret as byte array and do not save it into the client. Just store in the memory.

These steps do not guarantee the safety of the secret key, but makes reverse engineer's job really hard.

Semih
  • 69
  • 2
0

You can also try Dexguard to obfuscate and encrypt the data. Dexguard is made by the same guy that developed proguard.

Aegis
  • 5,573
  • 2
  • 29
  • 41
0

@Semih's answer was on the right track. The secret key part is what needs to be expanded upon.

  1. The secret key is between the application and the gateway server not to the underlying services.
  2. The gateway server is responsible for converting that key to something specific for the services.

The secret key is built using the following after the login process is complete

  1. the server generates a key pair specific for the client logging in.
  2. The server's public key is sent for encryption specific for the client logging in
  3. the app will generate a key pair for it's own purposes
  4. the app will send the public key encrypted with the server's public key
  5. the server will validate the public key is signed with their public key.

Any future requests would involve the following

All data being sent from client to the server would be encrypted using JWT the message would be signed by the app's private key and encrypted using the server's public key.

The problem is securing #1 anyone can login and get the process started, so how would you prevent that? The only way I can think of is to do a CAPTCHA check on the login.

The solution pushes the storage of the client secrets to the server rather than on the app itself and protecting it using the app's credentials.

Archimedes Trajano
  • 22,850
  • 10
  • 113
  • 154