2013-08-14 1 views
3

Я пытаюсь добавить свой 16-битный IV, используемый для шифрования моих данных в качестве последнего блока в массиве байтов, используемом для хранения зашифрованных данных. Я хочу сделать это, очевидно, для части расшифровки, чтобы я мог использовать абсолютно случайный 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. Append IV к концу зашифрованного массива
  4. байт данных
  5. Кодирование байтовой матрицы с использованием шестнадцатеричного

Список шагов для дешифрования:

  1. Decode шестигранных
  2. Перерыва зашифрованных данные и IV из массива байт
  3. данных Расшифровать с использованием IV

Что я имею дело, но я думаю, что Я хочу знать, есть ли «лучший» способ сделать это? Под этим я подразумеваю, есть ли набор или более простой способ сделать это, используя типы Cipher*? Я не могу их найти.

Спасибо.

+0

, добавив IV в зашифрованную строку, вы побеждаете всю ее цель - атака может просто игнорировать последние X символов/байтов –

ответ

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 дважды.

+0

Это в значительной степени то, что я был после. то, что у меня было, было немного свалкой мозга и выглядело довольно грязным. Спасибо за это! – MeanwhileInHell