KeyStore.getCertificate() floods the log with warnings

Viewed 745

Here's a really simple sample code:

val keyStore = KeyStore.getInstance("AndroidKeyStore")
keyStore.load(null)
if (keyStore.getCertificate("foobar") == null) {
     Log.d("kkkkk", "keystore not found")
}

Every time I call the getCertificate() method, the KeyStore puts a stacktrace into the log as a warning. Although the code works as expected still it's very frustrating because we use this function very extensively and our log became very hard to read. I experienced this on almost all phone that runs an least Android 9. Here is the beginning of the stacktrace:

2020-03-27 14:34:49.541 26536-26536/com.example.keystoreexceptiontest W/KeyStore: KeyStore exception
    android.os.ServiceSpecificException:  (code 7)
        at android.os.Parcel.createException(Parcel.java:2085)
        at android.os.Parcel.readException(Parcel.java:2039)
        at android.os.Parcel.readException(Parcel.java:1987)
        at android.security.keystore.IKeystoreService$Stub$Proxy.get(IKeystoreService.java:978)
        at android.security.KeyStore.get(KeyStore.java:236)
        at android.security.KeyStore.get(KeyStore.java:225)
        at android.security.keystore.AndroidKeyStoreSpi.engineGetCertificate(AndroidKeyStoreSpi.java:160)
        at java.security.KeyStore.getCertificate(KeyStore.java:1120)

After some search I found many similar issues but most of them recommend exactly this solution to solve the problem, like this one

Can you recommend something to get rid of those warnings?

1 Answers

Thanks for this question ! If possible, you should mark your own question as the accepted answer.

I had the very same issue, and followed the link you provided. Inside the answer from NullPointer (that is older than your question), there is this sentence that helped me to figure out what is happening :

This means, that there is no private key and you should first create and store a keypair before you search for it in the key store.

To rephrase it : if you search for a certificate that doesn't exists, you'll have this annoying log. You should first look for the private key (using keyStore.getKey) and if it exists you may look for the certificate.

To rewrite it, it may looks like this :

val privateKey = keyStore.getKey(keyAlias,null);
if (privateKey != null) {
    publicKey = keyStore.getCertificate(keyAlias)?.publicKey;
}
else
{
    createKey();
}
Related