web-dev-qa-db-ja.com

Android 9-キーストア例外Android.os.ServiceSpecificException

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

例外:

KeyStore例外Android.os.ServiceSpecificException:(コード7)Android.os.Parcel.createException(Parcel.Java:1956)at Android.os.Parcel.readException(Parcel.Java:1910)at Android.os.Parcel.readException (Parcel.Java:1860)Android.security.IKeystoreService $ Stub $ Proxy.get(IKeystoreService.Java:786)at Android.security.KeyStore.get(KeyStore.Java:195)at Android.security.keystore.AndroidKeyStoreSpi。 engine.getCertificateChain(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)com.phenodev.testenc.KeyStoreHelper.encrypt(KeyStoreHelper.Java:173)at com.phenodev.testenc.KeyStoreEncryptor.encrypt(KeyStoreEncryptor.Java:19)

修正にご協力ください。

24
phnmnn

最後に解決策を見つけました。 Android P (KeyStore.PrivateKeyEntry) keyStore.getEntry("alias", null)は秘密鍵を取得する適切な方法ではないためです。

この方法で秘密/公開鍵にアクセスすることで、この警告を取り除くことができました

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

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

AndroidKeyStoreからasymmetricKeyを取得するときに同じ問題が発生しました

キーを取得するためのDr Glassの回答に基づく私のソリューションは次のとおりでした:(aliasKeyはエイリアス文字列です)

PublicKey:

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

val asymmetricKeyPublicKey = 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 asymmetricKeyPrivateKey = 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
}

このコードでは、Android Pを使用してエミュレーターやデバイスに警告が表示されません。

1
MatPag

私の場合、キーがまだ存在していなかった場合にのみ、受け入れられた解決策としてキーを取得することさえ警告がまだありました。

警告はgetCertificate呼び出しから来ているので、それを避けるために:

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

PrivateKey privateKey = (PrivateKey) keyStore.getKey("alias", null);
PublicKey publicKey = privateKey != null ? keyStore.getCertificate("alias").getPublicKey() : null;
0
giroxiii