我正在尝试将用于加密我的数据的 16 位 IV 添加为用于保存加密数据的字节数组中的最后一个 block 。我显然想为解密部分执行此操作,以便我可以为每个加密/解密调用使用完全随机的 IV。我有以下用于测试目的:
public static String encrypt(String plainText) throws Exception {
encryptionKey = new SecretKeySpec(eKey.getBytes("UTF-8"), "AES");
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, encryptionKey, initialisationVector);
byte[] eDataAndIv = appendIvToEncryptedData(cipher.doFinal(plainText.getBytes("UTF-8")), initialisationVector.getIV());
return bytesToHexString(eDataAndIv);
}
public static String decrypt(String hexEncoded) throws Exception {
byte[] decodedBytes = hexStringToBytes(hexEncoded);
ArrayList<byte[]> al = retreiveIvFromByteArray(decodedBytes);
byte[] eData = al.get(0);
byte[] iv = al.get(1);
cipher.init(Cipher.DECRYPT_MODE, encryptionKey, new IvParameterSpec(iv));
return reconstructedPlainText(cipher.doFinal(eData));
}
private static byte[] appendIvToEncryptedData(byte[] eData, byte[] iv) throws Exception {
ByteArrayOutputStream os = new ByteArrayOutputStream();
os.write(eData);
os.write(iv);
return os.toByteArray();
}
private static ArrayList<byte[]> retreiveIvFromByteArray(byte[] dataPlusIv) {
ByteArrayOutputStream iv = new ByteArrayOutputStream(16);
ByteArrayOutputStream eData = new ByteArrayOutputStream();
iv.write(dataPlusIv, dataPlusIv.length - 16, 16);
eData.write(dataPlusIv, 0, dataPlusIv.length - 16);
ArrayList<byte[]> al = new ArrayList<byte[]>();
al.add(eData.toByteArray());
al.add(iv.toByteArray());
return al;
}
加密的步骤列表是:
- 创建IV
- 加密数据
- 将 IV 附加到加密数据字节数组的末尾
- 使用十六进制编码字节数组
解密步骤列表是:
- 解码十六进制
- 从字节数组中破解加密数据和IV
- 使用 IV 解密数据
我的方法有效,但我想我想知道的是,是否有“更好”的方法来做到这一点?我的意思是,是否有一套或更简单的方法来使用 Cipher*
类型来执行此操作?我找不到它们。
谢谢。
最佳答案
好吧,您当然可以避免冗长的retreiveIvFromByteArray
代码:
public static String decrypt(String hexEncoded) throws Exception {
byte[] decodedBytes = hexStringToBytes(hexEncoded);
int ivIndex = decodedBytes.length - 16;
cipher.init(Cipher.DECRYPT_MODE, encryptionKey,
new IvParameterSpec(decodedBytes, ivIndex, 16));
return reconstructedPlainText(cipher.doFinal(decodedBytes, 0, ivIndex));
}
这是你想的那种事情吗?
同样对于 appendIvToEncryptedData
,您可以创建一个适当长度的新字节数组,并使用 System.arraycopy
两次。
关于java - 将 IV 作为最终 block 添加到加密的字节数组中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18234234/