The problem
I'm trying to make a file encryptor for Android(Encryption algorithm is AES). Everything works fine until I try to encrypt/decrypt a large file. For example, when I try to encrypt a 771 MB file, it gives me this error:
E/AndroidRuntime: FATAL EXCEPTION: Thread-6
Process: com.suslanium.encryptor, PID: 27638
java.lang.OutOfMemoryError: Failed to allocate a 536869904 byte allocation with 25165824 free bytes and 254MB until OOM, target footprint 295637424, growth limit 536870912
at com.android.org.conscrypt.OpenSSLCipher$EVP_AEAD.expand(OpenSSLCipher.java:1219)
at com.android.org.conscrypt.OpenSSLCipher$EVP_AEAD.updateInternal(OpenSSLCipher.java:1336)
at com.android.org.conscrypt.OpenSSLCipher.engineUpdate(OpenSSLCipher.java:323)
at javax.crypto.Cipher.update(Cipher.java:1722)
at javax.crypto.CipherOutputStream.write(CipherOutputStream.java:158)
at com.suslanium.encryptor.MainActivity.encryptFileAES_GCM(MainActivity.java:912)
at com.suslanium.encryptor.MainActivity$18.run(MainActivity.java:794)
at java.lang.Thread.run(Thread.java:919)
Fragment of my code
public void encryptFileAES_GCM(File file , File fileToSave) throws Exception {
File keyEncrypted = new File(pathToStorage + "EncryptedKey.enc");
File IVEncrypted = new File(pathToStorage + "EncryptedKIV.enc");
if (keyEncrypted.exists() && IVEncrypted.exists()) {
FileInputStream fis = new FileInputStream(file);
FileOutputStream fos = new FileOutputStream(fileToSave);
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
SecretKeySpec keySpec = new SecretKeySpec(globalKey, "AES");
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, globalIV);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, gcmParameterSpec);
CipherOutputStream cos = new CipherOutputStream(fos, cipher);
int b;
byte[] d = new byte[512];
while ((b = fis.read(d)) != -1) {
cos.write(d, 0, b); //Line 912
}
cos.flush();
cos.close();
fis.close();
} else {
throw new Exception("Key or IV does not exist, encryption can't be done. Please create a key first.");
}
}
I already tried to search for some solutions, but with no luck. I have no idea what's wrong with this code. The buffer size is not too big, but even after decreasing it - nothing happens. Can anyone please help me?
UPDATE
Problem solved. When encrypting large files, I decided to use the following algorithm: split the file into chunks with X size, encrypt these chunks and put them in a zip archive. When decrypting large files, you need to extract the previously encrypted chunks from the archive, decrypt them and merge decrypted chunks into one file.