KeyStore "Неподдерживаемый параметр защиты" - PullRequest
2 голосов
/ 13 марта 2020

Я пытаюсь сохранить SecretKey в Android KeyStore, и я даже непосредственно следую документации, найденной здесь: KeyProtection: ключ AES для шифрования / описания в режиме GCM , который до сих пор не работает.

Кажется, я получаю следующее исключение при запуске:

java .security.KeyStoreException: неподдерживаемый параметр защиты

Это исключение специально возникает, когда я звоню keyStore.setEntry(...).

Я запускаю Android 10 на Samsung Galaxy S10, если это что-то меняет.

@RequiresApi(23)
private static KeyStore.ProtectionParameter getProtectionParameter() {
    return new KeyProtection.Builder(KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
            .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
            .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
            .build();
}

@RequiresApi(23)
private static SecretKey getSecretKey() throws Exception {
    KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
    keyStore.load(null);

    if (keyStore.containsAlias(KEY_ALIAS)) {
        final KeyStore.SecretKeyEntry secretKeyEntry = (KeyStore.SecretKeyEntry) keyStore
                .getEntry(KEY_ALIAS, null);
        return secretKeyEntry.getSecretKey();
    }

    final KeyGenerator keyGenerator = KeyGenerator
            .getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
    final KeyGenParameterSpec keyGenParameterSpec = new KeyGenParameterSpec.Builder(KEY_ALIAS,
            KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
            .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
            .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
            .build();

    keyGenerator.init(keyGenParameterSpec);
    SecretKey k = keyGenerator.generateKey();

    keyStore.setEntry(
        KEY_ALIAS,
        new KeyStore.SecretKeyEntry(k),
        getProtectionParameter()
    );

    return getSecretKey();
}

1 Ответ

0 голосов
/ 15 марта 2020

Оказывается, проблема была в моих строках KeyStore.getInstance и KeyGenerator.getInstance. Один из них использовал KeyStore.getDefaultType(), а другой - AndroidKeyStore. Изменение этого избавило от проблемы unsupported protection parameter.

Кроме того, после исправления возникла проблема с обновлением параметра защиты.

Оказывается, что следующий раздел кода неправильный

SecretKey k = keyGenerator.generateKey();

keyStore.setEntry(
    KEY_ALIAS,
    new KeyStore.SecretKeyEntry(k),
    getProtectionParameter()
);

Он пытается вставить ключ в хранилище ключей дважды, поскольку generateKey() уже вставляет его в хранилище ключей.

Полностью рабочий код будет выглядеть так:

@RequiresApi(23)
private static SecretKey getSecretKey() throws Exception {
    KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
    keyStore.load(null, null);

    final KeyStore.SecretKeyEntry secretKeyEntry = (KeyStore.SecretKeyEntry) keyStore
                .getEntry(KEY_ALIAS, null);
    if (secretKeyEntry != null) {
        return secretKeyEntry.getSecretKey();
    }

    final KeyGenerator keyGenerator = KeyGenerator
            .getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
    final KeyGenParameterSpec keyGenParameterSpec = new KeyGenParameterSpec.Builder(KEY_ALIAS,
            KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
            .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
            .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
            .build();

    keyGenerator.init(keyGenParameterSpec);
    SecretKey k = keyGenerator.generateKey();
    return getSecretKey();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...