java - KeyStore“不支持的保护参数”
问题描述
我正在尝试将 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();
}
解决方案
原来我遇到的问题是在我的KeyStore.getInstance
和KeyGenerator.getInstance
行中。其中一个正在使用KeyStore.getDefaultType()
where 另一个正在使用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();
}
推荐阅读
- c++ - Windows SAPI 错误:“GetVersionExA”:已声明已弃用
- c# - 访问另一个类/文件夹中的公共变量
- jmeter - Magento2 400 使用 Apache JMeter 获取产品的错误请求
- css - 如何恢复按钮默认样式?
- java - 将 Java stringbuilder 转换为 CLOB 并将输出作为 CLOB
- ios - 关于使用 xctest 在 swift、ios 中模拟单例的查询?
- python - 'TypeError("can't pickle generator objects"): Concurrent.future 与 Asyncio
- node.js - 如何使用 node js 创建谷歌云项目和服务帐户?
- c# - C# 8 使用声明范围混淆
- typescript - Vue Composition API TypeScript ref 类型不起作用