密钥库 "unsupported protection parameter"
KeyStore "unsupported protection parameter"
我正在尝试将 SecretKey 存储在 Android KeyStore 中,我什至直接按照此处找到的文档进行操作:KeyProtection: AES Key for Encryption / Description in GCM Mode,但仍然不起作用。
当我 运行 这个时,我似乎得到以下异常:
java.security.KeyStoreException: unsupported protection parameter
这个异常是在我调用keyStore.setEntry(...)
.
时专门引发的
我 运行宁 Android 10 在三星 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();
}
事实证明我遇到的问题是在 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();
}
我正在尝试将 SecretKey 存储在 Android KeyStore 中,我什至直接按照此处找到的文档进行操作:KeyProtection: AES Key for Encryption / Description in GCM Mode,但仍然不起作用。
当我 运行 这个时,我似乎得到以下异常:
java.security.KeyStoreException: unsupported protection parameter
这个异常是在我调用keyStore.setEntry(...)
.
我 运行宁 Android 10 在三星 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();
}
事实证明我遇到的问题是在 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();
}