直接使用从密钥库加载的SecretKey时,未对密钥用户进行身份验证 [英] Key user not authenticated when using a SecretKey directly as loaded from keystore
问题描述
我正在尝试使用在KeyStore中加载的带有SecretKey的Cipher加密数据,但始终会收到此错误:
I'm trying to encrypt data use Cipher with SecretKey loaded in KeyStore but always got this error :
原因:android.security.KeyStoreException:密钥用户未通过身份验证
我尝试自行创建SecretKeySpec.我正在使用android Q进行测试.
I tried creating SecretKeySpec myself it worked. I'm using android Q to test.
有人可以帮我解释一下问题吗?
Can anyone help me explain the problem?
我的代码
public Cipher createCipher() {
Cipher cipher;
try {
cipher = Cipher.getInstance(
KeyProperties.KEY_ALGORITHM_AES + "/"
+ KeyProperties.BLOCK_MODE_CBC + "/"
+ KeyProperties.ENCRYPTION_PADDING_PKCS7);
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
throw new RuntimeException("Failed to get Cipher", e);
}
return cipher;
}
public boolean initCipher() {
try {
cipher = createCipher();
SecretKey key = KeyStoreTools.getSecretKey(KEY_NAME);
cipher.init(Cipher.ENCRYPT_MODE, key);
return true;
} catch (KeyPermanentlyInvalidatedException e) {
KeyStoreTools.removeAlias(KEY_NAME);
return false;
} catch (Throwable e) {
throw new RuntimeException("Failed to init Cipher", e);
}
}
public static SecretKey getSecretKey(String keyName) {
Key key = getKey(keyName);
if (!keyExists(key)) {
key = generateKey(keyName);
}
return (SecretKey) key;
}
public static SecretKey generateKey(String keyName) {
SecretKey secretKey = null;
try {
KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, ANDROID_KEY_STORE);
KeyGenParameterSpec.Builder builder = new KeyGenParameterSpec.Builder(keyName,
KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT);
builder.setBlockModes(KeyProperties.BLOCK_MODE_CBC)
.setUserAuthenticationRequired(true)
.setEncryptionPaddings(
KeyProperties.ENCRYPTION_PADDING_PKCS7);
keyGenerator.init(builder.build());
secretKey = keyGenerator.generateKey();
} catch (NoSuchAlgorithmException | NoSuchProviderException exc) {
exc.printStackTrace();
} catch (Throwable e) {
throw new RuntimeException("Failed to generateKey", e);
}
return secretKey;
}
public String encrypt(Cipher cipher, byte[] dataToEncrypt) {
try {
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(dataToEncrypt);
byte[] enc = cipher.doFinal(md.digest());
String base64 = Base64.encodeToString(enc, Base64.DEFAULT);
return base64;
} catch (BadPaddingException | IllegalBlockSizeException | NoSuchAlgorithmException e ) {
e.printStackTrace();
}
return "";
}
推荐答案
我的问题抛出的原因是:
My issue throw because :
在将密钥标记为成功进行用户身份验证之前,我使用密码进行加密.因此,在onAuthenticationSucceeded中移动加密就可以了.
I encrypt using the cipher before the key has been flagged for successful user authentication. So move encrypt in onAuthenticationSucceeded and it's worked.
希望我的回答对别人有帮助.
Hope my answer will help someone else.
这篇关于直接使用从密钥库加载的SecretKey时,未对密钥用户进行身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!