我试图使用KeyStore中加载的SecretKey加密数据,但总是出现以下错误:
原因:android.security.KeyStoreException:密钥用户未通过身份验证
我试着自己创建SecretKeySpec,它成功了。我正在使用android Q进行测试。
有人能帮我解释一下这个问题吗?
我的代码
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 "";
}
我的问题抛出是因为:
在密钥被标记为成功的用户身份验证之前,我使用密码进行加密。因此,在onAuthenticationSuccessed中移动加密,它就起作用了。
希望我的回答能帮助其他人。