8

Assuming that a password for a keystore is not supplied by or bound to a user password (which more or less means its just a String or Array[] in the code somewhere), is it a sufficient protection that it just cannot or can only hardly be extracted out of the bytecode?

I know that the password for a keystore (JKS / BKS) is just used to verify the integrity of the keystore. Furthermore it is totally clear that I have to assume that an application runs in a more or less trusted environment to be "secure". But anyhow, is it possible to extract the password just from the apk file?

It just feels wrong to hardcode any password within the source of an application, so maybe there are some ideas, how to make it actually less threatening. E.g. would it be better to make the password configurable within an external configuration file or generate it randomly during installation of the app (and where should it then be stored)?

evildead
  • 4,607
  • 4
  • 25
  • 49
  • It is not hard to extract something out of bytecode / apks. If you decompile it you have roughly your sourcecode in plaintext again. I would not bother too much, if your app (or the secret you hide within) is worth hacking there will be one doing it. – zapl Feb 08 '14 at 14:02
  • I would say its worth hacking. :) So for me its important that if a password is compromised, other app-installations are not infected. So creating a password for an install seems at least a "better" solution. – evildead Feb 08 '14 at 15:58
  • In case of keystore passwords, I could simply add a `println` to e.g. [Keystore.load](https://android.googlesource.com/platform/libcore/+/master/luni/src/main/java/java/security/KeyStore.java) into my custom firmware and would not even need to touch your app. That's pretty simple. Dexguard does not protect against calling untrusted platform code, you would need to roll your own implementation so I'd need to sniff your network traffic or read the value from a memory dump. – zapl Feb 08 '14 at 19:42

3 Answers3

4

is it a sufficient protection that it just cannot or can only hardly be extracted out of the bytecode?

"Sufficient" is a subjective term; only you can determine what you feel is sufficient for you.

is it possible to extract the password just from the apk file?

Yes, as APK files can be decompiled, unencrypted network conversations can be sniffed, etc.

how to make it actually less threatening

You can buy a license for DexGuard and use it, as that will encrypt hard-coded strings like your password. Whether that is worth the extra defense is your decision.

would it be better to make the password configurable within an external configuration file

Anyone who roots the device could get at the file.

or generate it randomly during installation of the app (and where should it then be stored)?

It would be stored somewhere that is available to rooted device users, at minimum.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • so this would mean, buy dexGuard or live with it? – evildead Feb 08 '14 at 15:54
  • @evildead: You could attempt to roll your own encryption, but you wind up chasing your tail (where do you store *that* encryption key?), and you're unlikely to do better than DexGuard. I am not aware of any other off-the-shelf solutions. – CommonsWare Feb 08 '14 at 15:57
  • Yeah, it makes no sense to build upon own encryption. Quite sad that there is no common -free- solution. Else, I guess, I would already found it here or while googleing. :) – evildead Feb 08 '14 at 16:05
  • @evildead even dexguard must store it's decryption secret within your app and (although that may not have happened so far because they are probably good at hiding it) that secret is within the hands of the attacker and can be found. An open source version of that would spoil all the secret way they use and just giving out such software for free is unlikely because you have to improve it in secret all the time - a few people working on hiding vs many people working on unhiding. – zapl Feb 08 '14 at 19:27
3

It is quite common to encrypt keystores with a password, but it is not neccesarily required.

Storing the password close to the keystore is more or less equivalent to having a keystore that is not encrypted. That may be perfectly ok. It is i.e. not uncommon to have unencrypted keystores with both certificates an private keys on servers where the keystore file is protected by other means.

The kind of attack you seem to be trying to protect against here is if someone are able to change the content of the keystore. A password could be used to verify the integrity of the keystore, but only if it is unknown to the attacker. It can't think of a typical scenario where an attacker would have access to your keystore but not have access to the bytecode of your application or the other configuration of the application.

The file system for an application in Android is reasonable secure, but not bullet proof in any way. If you don't trust that file system, you will need to encrypt the keystore with a password the the user types in or that is fetched from somewhere else outside of the device. On the other hand, if you trust the file system you don't actually have to encrypt the keystore at all (or you may encrypt it with a well known password if that makes your development easier).

sstendal
  • 3,148
  • 17
  • 22
1

Try using null instead of the password (see this question)

final KeyStore keyStore = KeyStore.getInstance("BKS");
    keyStore.load(context.getResources().openRawResource(R.raw.serverkeys), null);

    final KeyManagerFactory keyManager = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
    keyManager.init(keyStore, null);

    final TrustManagerFactory trustFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
    trustFactory.init(keyStore);

    sslContext = SSLContext.getInstance("TLS");
    sslContext.init(keyManager.getKeyManagers(), trustFactory.getTrustManagers(), null);
Community
  • 1
  • 1
Lucas Jota
  • 1,863
  • 4
  • 24
  • 43