Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/198.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Android 9-密钥库异常Android.os.ServiceSpecificException_Java_Android_Keystore_Android Keystore - Fatal编程技术网

Java Android 9-密钥库异常Android.os.ServiceSpecificException

Java Android 9-密钥库异常Android.os.ServiceSpecificException,java,android,keystore,android-keystore,Java,Android,Keystore,Android Keystore,如果我在Android 9上运行此代码,我会收到以下异常: private static KeyStore.PrivateKeyEntry getPrivateKeyEntry(String alias) { try { KeyStore ks = KeyStore .getInstance(SecurityConstants.KEYSTORE_PROVIDER_ANDROID_KEYSTORE);

如果我在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;
        }
    }
例外情况:

密钥库异常 android.os.ServiceSpecificException:(代码7) 位于android.os.Parcel.createException(Parcel.java:1956) 在android.os.Parcel.readException(Parcel.java:1910) 位于android.os.Parcel.readException(Parcel.java:1860) 位于android.security.IKeystoreService$Stub$Proxy.get(IKeystoreService.java:786) 位于android.security.KeyStore.get(KeyStore.java:195) 位于android.security.keystore.androidkeystrespi.engineGetCertificateChain(androidkeystrespi.java:118) 位于java.security.keystrespi.Engineegentry(keystrespi.java:484) 位于java.security.KeyStore.getEntry(KeyStore.java:1560) 在com.phenodev.testen.keystrehelper.getPrivateKeyEntry(keystrehelper.java:151)上 在com.phenodev.testenc.keystrehelper.encrypt(keystrehelper.java:173)上 在com.phenodev.testenc.keystreecryptor.encrypt(keystreencryptor.java:19)上


请帮我修一下。

我终于找到了解决办法。看起来好像是因为Android P
(KeyStore.PrivateKeyEntry)KeyStore.getEntry(“别名”,null)
不是获取私钥的正确方法

通过这种方式访问私钥/公钥,我可以消除此警告

KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);

PrivateKey privateKey = (PrivateKey) keyStore.getKey("alias", null);
PublicKey publicKey = keyStore.getCertificate("alias").getPublicKey();

AndroidKeyStore

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

公钥:

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
}
私钥:

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
}

有了这段代码,我在仿真器和/或安卓p设备中没有警告,我找到了一个解决方案,如何删除警告,如果你也能测试一下,那就太好了。实际上,调用方法的顺序是个问题

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)
}
这是调用方法的正确顺序

当你这样做的时候:

val privateKey = keyStore.getKey(alias, null)
val certificate = keyStore.getCertificate(alias)

if (privateKey != null && certificate != null) {
    KeyPair(certificate.publicKey, privateKey as PrivateKey)
}
您将收到以下警告(因为keyStore.getCertificate(别名):

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

现在有了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
        }
}

我也有同样的问题:-(谢谢!使用
getKey()
getCertificate()
方法而不是
getEntry()
确实解决了这个问题。虽然我目前正以这种方式提取密钥,但在使用API 29的模拟器中,我在第一次尝试获取密钥时(仅第一次)仍然收到警告。如果我终止进程并再次启动应用程序,警告就会消失。为了清楚起见,我在API级别21上对其进行了测试(以查看是否需要根据API版本使用不同的逻辑),但它似乎也能很好地工作。它并不能解决这个问题,至少在安卓Q,beta 2上是如此。而且,例外情况依然存在,所以不仅仅发生在你第一次启动应用程序时(参考上面的评论,上面的评论是这样说的)。
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
        }
}