Я работаю над классом для шифрования / дешифрования больших файлов, поэтому я пытаюсь использовать потоки вместо байтовых массивов, чтобы избежать исключений OutOfMemory.
В методе шифрования я добавляю случайную соль и iv в начало зашифрованного файла, и он работает нормально, а вот код:
public File encryptFile(File inputFile, File outPutFile, String password, ProgressBar progressBar, Label progressPercentage){
//Create IV
byte[] ivBytes = new byte[16];
SecureRandom random1 = new SecureRandom();
random1.nextBytes(ivBytes);
IvParameterSpec iv = new IvParameterSpec(ivBytes);
//Create the key with the salt
SecureRandom random = new SecureRandom();
byte[] salt = new byte[SALT_SIZE];
random.nextBytes(salt);
SecretKeySpec keySpec = generateAesKey(password, salt);
//Create and Init the cipher
Cipher c = Cipher.getInstance("AES/CBC/"+padding);
c.init(Cipher.ENCRYPT_MODE, keySpec, iv);
byte[] buf = new byte[8192];
FileInputStream in = new FileInputStream(inputFile);
FileOutputStream out = new FileOutputStream(outPutFile);
int nread;
int progress = 0;
byte[] ivAndSalt = new byte[ivBytes.length + salt.length];
System.arraycopy(ivBytes,0, ivAndSalt,0, ivBytes.length );
System.arraycopy(salt, 0, ivAndSalt, ivBytes.length, salt.length);
out.write(ivAndSalt);
while((nread = in.read(buf)) != -1) {
byte[] enc = c.update(buf, 0, nread);
out.write(enc);
progress++;
}
Затем я пытаюсь получить iv и соль в методе расшифровки, а затем расшифровать оставшуюся часть файла в выходной файл с помощью FileInputStream.getChannel.position()
:
public File decryptFile(File inputFile, File outPutFile, String password, ProgressBar progressBar, Label progressPercentage) {
//Create and Init Cipher
Cipher c = Cipher.getInstance("AES/CBC/" + padding);
FileInputStream in = new FileInputStream(inputFile);
FileOutputStream out = new FileOutputStream(outPutFile);
//Getting the iv and salt
byte[] ivBytes = new byte[16];
byte[] salt = new byte[SALT_SIZE];
byte[] ivAndSalt = new byte[ivBytes.length+SALT_SIZE];
in.read(ivAndSalt, 0, ivBytes.length+SALT_SIZE);
System.arraycopy(ivAndSalt, 0, ivBytes, 0, ivBytes.length);
System.arraycopy(ivAndSalt, ivBytes.length, salt, 0, SALT_SIZE);
IvParameterSpec iv =new IvParameterSpec(ivBytes);
SecretKeySpec keySpec = generateAesKey(password, salt);
c.init(Cipher.DECRYPT_MODE, keySpec, iv);
in.getChannel().position(ivAndSalt.length);
int nread;
int progress = 0;
byte[] buf = new byte[8192];
while((nread = in.read(buf)) != -1) {
byte[] enc = c.update(buf, 0, nread);
out.write(enc);
progress++;
/*if (enc.length / 8192 != 0)
System.out.println((nread*progress) + "%");*/
}
System.out.println("Size of out before doFinal(): " + out.getChannel().size());
byte[] enc = c.doFinal();
out.write(enc);
System.out.println("Size of out after doFinal(): " + out.getChannel().size());
return outPutFile;
}
Я не получил ошибку при вызове decryptFile (), но созданный файл поврежден, и это означает, что где-то в расшифровке существует проблема.