Home » Android » Good Practice: How to handle keystore passwords in android/java?

Good Practice: How to handle keystore passwords in android/java?

Posted by: admin June 15, 2020 Leave a comment

Questions:

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)?

How to&Answers:

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.

Answer:

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).

Answer:

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);