Android 9 - KeyStore exception android.os.ServiceSpecificException
Finally I found a solution. It looks like since Android P (KeyStore.PrivateKeyEntry) keyStore.getEntry("alias", null)
is not a proper way to get private key.
I was able to get rid of this warning by accessing private/public key this way
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");keyStore.load(null);PrivateKey privateKey = (PrivateKey) keyStore.getKey("alias", null);PublicKey publicKey = keyStore.getCertificate("alias").getPublicKey();
I had the same problem retrieving an asymmetricKey from AndroidKeyStore
My solution based on Dr Glass answer to get keys is the following: (aliasKey is your alias string)
PublicKey:
val keyStore = KeyStore.getInstance("AndroidKeyStore")keyStore.load(null)val asymmetricPublicKey = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { keyStore.getCertificate(aliasKey).publicKey} else { val asymmetricKey = keyStore.getEntry(aliasKey, null) as KeyStore.PrivateKeyEntry asymmetricKey.certificate.publicKey}
PrivateKey:
val keyStore = KeyStore.getInstance("AndroidKeyStore")keyStore.load(null)val asymmetricPrivateKey = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { keyStore.getKey(aliasKey, null) as PrivateKey} else { val asymmetricKey = keyStore.getEntry(aliasKey, null) as KeyStore.PrivateKeyEntry asymmetricKey.privateKey}
and with this code I have no warning in the emulator and/or device with Android P
I found a solution how to remove the warning, would be great if you can test it all as well. Actually the order of calling the methods is the problem.
val privateKey = keyStore.getKey(alias, null)val publicKey = if (privateKey != null) keyStore.getCertificate(alias).publicKey else nullif (privateKey != null && publicKey != null) { KeyPair(publicKey, privateKey as PrivateKey)}
This is the correct ordering of how to call the methods.
When you do it like this:
val privateKey = keyStore.getKey(alias, null)val certificate = keyStore.getCertificate(alias)if (privateKey != null && certificate != null) { KeyPair(certificate.publicKey, privateKey as PrivateKey)}
You will receive the following warning (because of keyStore.getCertificate(alias):
KeyStore exceptionandroid.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)
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.
Now with the answer of MatPag it should look like this:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { val privateKey = keyStore.getKey(alias, null) val publicKey = if (privateKey != null) keyStore.getCertificate(alias).publicKey else null return if (privateKey != null && publicKey != null) { KeyPair(publicKey, privateKey as PrivateKey) } else { null }} else { val asymmetricKey = keyStore.getEntry(alias, null) as KeyStore.PrivateKeyEntry val privateKey = asymmetricKey.privateKey val publicKey = if(privateKey != null) asymmetricKey.certificate.publicKey else null return if(privateKey != null && publicKey != null) { KeyPair(publicKey, privateKey as PrivateKey) } else { null }}