【问题标题】:KeyStore "unsupported protection parameter"KeyStore“不支持的保护参数”
【发布时间】:2020-03-12 21:37:25
【问题描述】:

我正在尝试将 SecretKey 存储在 Android KeyStore 中,我什至直接按照此处找到的文档进行操作:KeyProtection: AES Key for Encryption / Description in GCM Mode,但仍然无法正常工作。

当我运行这个时,我似乎得到了以下异常:

java.security.KeyStoreException: 不支持的保护参数

这个异常是在我调用keyStore.setEntry(...) 时专门引发的。

我在三星 Galaxy S10 上运行 Android 10,如果这有什么不同的话。

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

【问题讨论】:

    标签: java android cryptography android-keystore


    【解决方案1】:

    原来我遇到的问题是在我的KeyStore.getInstanceKeyGenerator.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();
    }
    

    【讨论】:

      猜你喜欢
      • 2018-05-15
      • 2023-03-31
      • 1970-01-01
      • 2020-10-17
      • 1970-01-01
      • 2013-01-21
      • 2012-04-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多