1

First of all, I don't have a strong background in information security and just need some basic guidelines for my question. Posted the same question on cryptography stackexchange, but this seems to be much more appropriate place.

So there are an Android application and a remote HTTP(S) server. To access the server's functionality the application needs to receive a token (generated for each individual device based on device id), and to do this app has to provide a valid API key.

We assume the communication with the server is secure and the main danger for an attack is to reverse-engineer the application. There is no 100% defense against reverse-engineering, but app's dex executable (virtual machine bytecode) is obfuscated using specialized tools.

So the question is what the best way to store the API key?

Currently I'm considering two options:

  1. API key is stored inside native code portion of the application, not in plain text, but encrypted with an algorithm that is very complex and thus harder to reverse engineer than VM bytecode. So I need a method to eliminate replay attack, where an attacker can just call a specific native function and get the key. We assume that all native code is black box to an attacker.
  2. Do not use a fixed API key at all, but use some kind of dynamic API key to authenticate on the server to receive a token. Plus implement all security-related stuff in native code.
2

API key is stored inside native code portion of the application, not in plain text, but encrypted with an algorithm that is very complex and thus harder to reverse engineer than VM bytecode. So I need a method to eliminate replay attack, where an attacker can just call a specific native function and get the key. We assume that all native code is black box to an attacker.

This is security through obscurity. While it makes some sense to slow down attacker, it is by no means a mechanism to provide real security, e.g. attack prevention.

So the question is what the best way to store the API key?

To define the defences you need to define threat model: what kind of threats are you protecting against? User reverse-engineering? Malware apps? Remotely rooting the device via some vulnerability? These threat vectors suggest different defences.

Putting apart security through obscurity, you might want to protect the API key cryptographically:

  1. Make it random and cryptographically strong (e.g. hard to brute force)
  2. Encrypt it with a secret, which is not stored on the device: PIN / password / fingerprint.
  3. If you're protecting against the owner of the device (which it slightly feels like from what you're writing), there's no good threat prevention tactic, sorry.
  4. To avoid replay attacks, you will need dynamic key, which gets updated upon every successful communication with server.

Notes:

  1. Try to avoid encrypted with an algorithm that is very complex and thus harder to reverse engineer than VM bytecode, because that abuses Kerckhoffs's principle (https://en.wikipedia.org/wiki/Kerckhoffs's_principle), and it leads you to dark places.
  2. Rely on good proven cryptography and managing the secret properly. Deriving / hiding the secret near protected data will end up bad sooner or later - that's steel security through obscurity, a good additional feature yet no foundation for good security.
  • Thanks for the reply, the main goal of the app security system is to make it impossible or much harder for an attacker to use server endpoints even if exact URLs would be discovered. Ideally only the app should be authorized to interact with the server. So the main threat is that an attacker could reverse engineer the app and discover a way to interact with server directly. I understand that it is not possible to protect from a directed professional attacker by storing the key on a storage that he/she can access. The objective is to make the process of discovering the key as hard as possible. – bvk256 Dec 26 '16 at 14:30
  • Well, then you need proper authentication on these endpoints, and protection for the authentication tokens used. That should include: (1) safe onboarding procedure (pre-sharing secret or key, or registration over really trusted channel), (2) protecting the key that comes out of onboarding (ideally via encrypting with a secret, which is stored in user's head, like password or pin), (3) making sure that authentication protocol itself does not leak data which can be used to replay authentication (ideally - via ZKP protocol, which even in theory does not leak sufficient data to replay). – Eugene Dec 28 '16 at 8:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.