Вопрос

I am trying to add my 16-bit IV used to encrypt my data as the final block in the byte array used to hold the encrypted data. I want to do this obviously for the decryption part so that I can use a completely random IV for each encryption/decryption call. I have the following for testing purposes:

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;
}

The list of steps for encryption are:

  1. Create IV
  2. Encrypt data
  3. Append IV to end of encrypted data byte array
  4. Encode byte array using hex

The list of steps for decryption are:

  1. Decode hex
  2. Break encrypted data and IV from byte array
  3. Decrypt data using IV

What I have works, but I guess what I want to know is, is there a "better" way of doing this? By that I mean, is there a set, or simpler, way to do this using the Cipher* types? I can't find them.

Thanks.

Это было полезно?

Решение

Well you can certainly avoid the long-winded retreiveIvFromByteArray code:

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));
}

Is that the sort of thing you were thinking of?

Likewise for the appendIvToEncryptedData you could just create a new byte array of the appropriate length, and use System.arraycopy twice.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top