Java Android 9 - KeyStore 异常 android.os.ServiceSpecificException

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/52024752/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 00:19:02  来源:igfitidea点击:

Android 9 - KeyStore exception android.os.ServiceSpecificException

javaandroidkeystoreandroid-keystore

提问by phnmnn

If I run this code on Android 9, I receive the follow exception:

如果我在 Android 9 上运行此代码,则会收到以下异常:

private static KeyStore.PrivateKeyEntry getPrivateKeyEntry(String alias) {
        try {
            KeyStore ks = KeyStore
                    .getInstance(SecurityConstants.KEYSTORE_PROVIDER_ANDROID_KEYSTORE);
            ks.load(null);
            KeyStore.Entry entry = ks.getEntry(alias, null);

            if (entry == null) {
                Log.w(TAG, "No key found under alias: " + alias);
                Log.w(TAG, "Exiting signData()...");
                return null;
            }

            if (!(entry instanceof KeyStore.PrivateKeyEntry)) {
                Log.w(TAG, "Not an instance of a PrivateKeyEntry");
                Log.w(TAG, "Exiting signData()...");
                return null;
            }
            return (KeyStore.PrivateKeyEntry) entry;
        } catch (Exception e) {
            Log.e(TAG, e.getMessage(), e);
            return null;
        }
    }

Exception:

例外:

KeyStore exception android.os.ServiceSpecificException: (code 7) at android.os.Parcel.createException(Parcel.java:1956) at android.os.Parcel.readException(Parcel.java:1910) at android.os.Parcel.readException(Parcel.java:1860) at android.security.IKeystoreService$Stub$Proxy.get(IKeystoreService.java:786) at android.security.KeyStore.get(KeyStore.java:195) at android.security.keystore.AndroidKeyStoreSpi.engineGetCertificateChain(AndroidKeyStoreSpi.java:118) at java.security.KeyStoreSpi.engineGetEntry(KeyStoreSpi.java:484) at java.security.KeyStore.getEntry(KeyStore.java:1560) at com.phenodev.testenc.KeyStoreHelper.getPrivateKeyEntry(KeyStoreHelper.java:151) at com.phenodev.testenc.KeyStoreHelper.encrypt(KeyStoreHelper.java:173) at com.phenodev.testenc.KeyStoreEncryptor.encrypt(KeyStoreEncryptor.java:19)

KeyStore 异常 android.os.ServiceSpecificException: (code 7) at android.os.Parcel.createException(Parcel.java:1956) at android.os.Parcel.readException(Parcel.java:1910) at android.os.Parcel.readException (Parcel.java:1860) at android.security.IKeystoreService$Stub$Proxy.get(IKeystoreService.java:786) at android.security.KeyStore.get(KeyStore.java:195) at android.security.keystore.AndroidKeyStoreSpi。 engineGetCertificateChain(AndroidKeyStoreSpi.java:118) 在 java.security.KeyStoreSpi.engineGetEntry(KeyStoreSpi.java:484) 在 java.security.KeyStore.getEntry(KeyStore.java:1560) 在 com.phenodev.testenc.KeyStoreHelper.getPrivateHelperKeyEntry(KeyStore .java:151) 在 com.phenodev.testenc.KeyStoreHelper.encrypt(KeyStoreHelper.java:173) 在 com。phenodev.testenc.KeyStoreEncryptor.encrypt(KeyStoreEncryptor.java:19)

Please help to fix it.

请帮助修复它。

采纳答案by Dr Glass

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.

最后我找到了解决方案。看起来因为 Android P(KeyStore.PrivateKeyEntry) keyStore.getEntry("alias", null)不是获取私钥的正确方法。

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

回答by MatPag

I had the same problem retrieving an asymmetricKey from AndroidKeyStore

我有同样的问题从检索非对称密钥 AndroidKeyStore

My solution based on Dr Glass answer to get keys is the following: (aliasKey is your alias string)

我基于 Dr Glass 的答案获取密钥的解决方案如下:(aliasKey 是您的别名字符串)

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

使用此代码,我在模拟器和/或 Android P 设备中没有警告

回答by NullPointer

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 null

if (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.getCertificate(alias)):

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)

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

这意味着,没有私钥,您应该先创建并存储一个密钥对,然后再在密钥库中搜索它。

Now with the answer of MatPag it should look like this:

现在有了 MatPag 的答案,它应该是这样的:

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
        }
}