2017-02-22 19 views
0

Вот мой класс шифрования:Попытка удалить последние 16 байт, что я добавляемые на байт [] (который является IV), а затем расшифровать

public static void encrypt(byte[] file, String password, String fileName, String dir) throws Exception { 

    SecureRandom r = new SecureRandom(); 
    //128 bit IV generated for each file 
    byte[] iv = new byte[IV_LENGTH]; 
    r.nextBytes(iv); 
    IvParameterSpec ivspec = new IvParameterSpec(iv); 
    SecretKeySpec keySpec = new SecretKeySpec(password.getBytes(), "AES"); 

    Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); 
    cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivspec); 

    FileOutputStream fos = new FileOutputStream(dir + fileName); 
    fos.write(iv); 

    CipherOutputStream cos = new CipherOutputStream(fos, cipher); 

    // Have to append IV -------- 

    cos.write(file); 

    fos.flush(); 
    cos.flush(); 
    cos.close(); 
    fos.close(); 
} 

Это мой метод дешифрования:

public static void decrypt(byte[] file, String password, String fileName, String dir) throws Exception 
{ 
    // gets the IV 
    int ivIndex = file.length - 16; 

    byte[] truncatedFile = Arrays.copyOfRange(file, 0, file.length - 16); 

    SecretKeySpec keySpec = new SecretKeySpec(password.getBytes(), "AES"); 

    Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); 
    cipher.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(truncatedFile, ivIndex, 16)); 

    //IvParameterSpec ivspec = new IvParameterSpec(iv); 
    // 
    //cipher.init(Cipher.DECRYPT_MODE, keySpec, ivspec); 

    FileOutputStream fos = new FileOutputStream(dir + fileName); 
    CipherOutputStream cos = new CipherOutputStream(fos, cipher); 

    cos.write(file); 
    fos.flush(); 
    cos.flush(); 
    cos.close(); 
    fos.close(); 
} 

}

Как вы можете видеть, я сгенерировал 16-байтовый IV, который я добавил в конец зашифрованного файла. Это так, что я снимаю IV для дешифрования, а также у каждой подачи есть уникальный IV. Сейчас я получаю сообщение об ошибке:

java.lang.IllegalArgumentException: IV буфер слишком короткий для заданного смещения/длины комбинации

Помимо проблемы, порождающей ошибку, моя логика правильная? будет ли это работать?

ответ

4

I generated a 16 byte long IV that I have appended to the end of the encrypted file.

Нет, вы этого не сделали. Вы pre -ложите его. В любом случае это лучшая идея. Поэтому сначала вы должны прочитать его, а затем построить свои Cipher и CipherInputStream и расшифровать оставшуюся часть входного потока файла. Для этого вам не нужно читать весь файл в памяти:

public static void decrypt(File file, String password) throws Exception 
{ 
    byte[] iv = new byte[16]; 
    DataInputStream dis = new DataInputStream(new FileInputStream(file)); 
    dis.readFully(iv); 

    SecretKeySpec keySpec = new SecretKeySpec(password.getBytes(), "AES"); 

    Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); 
    cipher.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(iv)); 
    CipherInputStream cis = new CipherInputStream(dis, cipher); 

    // Now just read plaintext from `cis` and do whatever you want with it. 

    cis.close(); 
} 
+0

Как бы отделить два, если IV в начале? – champskee

+0

Как я сказал. Прочитайте первые 16 байтов через 'FileInputStream', а затем передайте тот же' FileInputStream' в 'CipherInputStream'. – EJP

+0

Не могли бы вы показать пример? Я продолжаю получать ошибки. Его долгий день смотрел на тот же код. – champskee

Смежные вопросы