java - Android解密抛出java.security.InvalidAlgorithmParameterException:IV必须在CBC模式下指定
问题描述
尽管检查了我的 IV 和派生密钥对于加密和解密都是相等的,但它仍然会引发相同的错误。字节数组将加密没有问题,但解密总是失败。我的解密和加密代码如下:
private final static int BLOCK_SIZE = 256;
private final static int IV_SIZE = 16;
private final static int ITERATION_COUNT = 10;
private final static String ENCRYPTION_ALGORITHM = "PBKDF2WithHmacSHA256";
private final static String ALGORITHM = "AES/CBC/PKCS5Padding";
public byte[] encryptByteArray(byte[] plaintext, String fileName) throws InvalidKeyException
{
extractIVfromName(fileName);
genKey();
try {
Cipher cipher = Cipher.getInstance(ALGORITHM);
GCMParameterSpec parameterSpec = new GCMParameterSpec(BLOCK_SIZE, iv);
Log.d("encryptByteArray", "Size: " + plaintext.length + " IV SPEC: " +
Base64.encodeToString(parameterSpec.getIV(), Base64.DEFAULT) + "DerivedKey: " +
Base64.encodeToString(derivedKey.getEncoded(), Base64.DEFAULT));
cipher.init(Cipher.ENCRYPT_MODE, derivedKey, parameterSpec);
return cipher.doFinal(plaintext);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
}
return null;
}
在这里我们进行了解密,发生错误的地方:
public byte[] decryptByteArray(byte[] ciphertext, String fileName) throws InvalidKeyException
{
extractIVfromName(fileName);
genKey();
try {
//IV fails for some reason
Cipher cipher = Cipher.getInstance(ALGORITHM);
GCMParameterSpec parameterSpec = new GCMParameterSpec(BLOCK_SIZE, iv);
Log.d("decryptByteArray", "Size: " + ciphertext.length + " IV SPEC: " +
Base64.encodeToString(parameterSpec.getIV(), Base64.DEFAULT) + "DerivedKey: " +
Base64.encodeToString(derivedKey.getEncoded(), Base64.DEFAULT));
cipher.init(Cipher.DECRYPT_MODE, derivedKey, parameterSpec);
return cipher.doFinal(ciphertext);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
return null;
}
调试日志的一个例子给出了这个:
2020-07-26 22:40:03.667 9089-9089/com.iso.gallery256 D/decryptByteArray: Size: 45312 IV SPEC: NWZmYmUzZGItZGE4MS00Yw==
DerivedKey: pa2OYoRLjTphldeSi1L6EQCmlXTzQJLeXgPIuu6kRus=
2020-07-26 22:40:00.184 9089-9089/com.iso.gallery256 D/encryptByteArray: Size: 45307 IV SPEC: NWZmYmUzZGItZGE4MS00Yw==
DerivedKey: pa2OYoRLjTphldeSi1L6EQCmlXTzQJLeXgPIuu6kRus=
我认为问题不在于 IV 或密钥的生成方式,因为它们在解密和加密方面完全相同,而是与我的密码选项有关。
解决方案
推荐阅读
- dart - 在列表上循环以显示位于彼此后面
- excel - VBA 使用 XMLDocument 解析 XML
- mysql - 如何从查询动态创建列名?
- php - MySQL 服务器已消失,(错误 2006)在 Windows 10 上
- woocommerce - 产品图片下的 WooCommerce 商店页面空白
- ios - 背景颜色的全局变化
- java - Issue in importing the Firestore and implementing addOnSuccessListener
- python - 如何在 django html 中添加一个选择选项,它是另一个选择的子项
- react-native - 收到“reactnativenavigationtest”登录错误
- node.js - Unable to run a node.js file with @babel/preset-env