Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android 4.3 KeyStore - chain == null while trying to retrieve keys

Following this blog, I'm using this code to create and store a KeyPair in Android KeyStore:

Context ctx = getApplicationContext();
Calendar notBefore = Calendar.getInstance();
Calendar notAfter = Calendar.getInstance();
notAfter.add(1, Calendar.YEAR);
KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(ctx).
setAlias(RSA_KEYS_ALIAS).setSubject(
  new X500Principal(String.format("CN=%s, OU=%s", 
    getApplicationName(), ctx.getPackageName()))).
setSerialNumber(BigInteger.ONE).
setStartDate(notBefore.getTime()).setEndDate(notAfter.getTime()).build();

KeyPairGenerator kpGenerator;
try {
    kpGenerator = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore");

    kpGenerator.initialize(spec);
    kpGenerator.generateKeyPair();
} catch (Exception e) {
    showException(e);
}

When I try to retrieve public key from the KeyStore using this code, a NullPointerException with the message chain == null is thrown.

public RSAPublicKey getRSAPublicKey() {
    RSAPublicKey result = null;
    try {
        KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
        keyStore.load(null);
        KeyStore.PrivateKeyEntry keyEntry = 
            (KeyStore.PrivateKeyEntry) keyStore.getEntry(RSA_KEYS_ALIAS, null); // --< exception is thrown here
        result = (RSAPublicKey) keyEntry.getCertificate().getPublicKey();
    }
    } catch (Exception e) {
        showException(e);
    }
    return result;
}

The same goes with the the code to retrieve private key.

Update:

I compared my code with Google BasicAndroidKeyStore sample. The mechanism to generate, store and retrieve the key pair in that sample is virtually the same to what I've implemented. I'm puzzled as to why this code has stopped functioning after a few months of perfectly working.

Any suggestions or hints would be appreciated.

like image 850
iMan Biglari Avatar asked Jun 01 '14 06:06

iMan Biglari


People also ask

What is keystore password in Android?

The Android Keystore system lets you store cryptographic keys in a container to make them more difficult to extract from the device. Once keys are in the keystore, you can use them for cryptographic operations, with the key material remaining non-exportable.

How secure is Android keystore?

KeyStore Introduction The Android Keystore provides APIs to perform cryptographic operations within this trusted environment and receive the result. It was introduced in API 18 (Android 4.3). A strongbox backed Android Keystore is currently the most secure and recommended type of keystore.


2 Answers

Apparently names in Android KeyStore must be unique amongst all Apps. I had another app which used the same name for its keys. After changing the the common library used by both apps to create and and use keys to include package name in its key names, the problem went away...

like image 116
iMan Biglari Avatar answered Oct 11 '22 04:10

iMan Biglari


In my case, I had multiple calls to obtain the KeyStore at nearly the same time. I had to create a single instance and refer to that if it existed, otherwise KeyStore.getInstance("AndroidKeyStore") returned null and raised an Exception. To protect against multiple async requests causing a crash, use a stored instance from just one KeyStore.getInstance().

like image 26
Thomas Avatar answered Oct 11 '22 03:10

Thomas