3

我正在尝试将用于加密数据的 16 位 IV 添加为用于保存加密数据的字节数组中的最后一个块。我显然想为解密部分执行此操作,以便我可以为每个加密/解密调用使用完全随机的 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;
}

加密步骤列表如下:

  1. 创建 IV
  2. 加密数据
  3. 将 IV 附加到加密数据字节数组的末尾
  4. 使用十六进制编码字节数组

解密步骤列表如下:

  1. 解码十六进制
  2. 从字节数组中破解加密数据和 IV
  3. 使用 IV 解密数据

我有什么作品,但我想我想知道的是,有没有“更好”的方式来做到这一点?我的意思是,是否有一套或更简单的方法来使用这些Cipher*类型来做到这一点?我找不到他们。

谢谢。

4

1 回答 1

3

那么你当然可以避免冗长的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两次。

于 2013-08-14T14:23:35.627 回答