I'm doing a program to encrypt and decrypt files on android, could someone help me?

1

I can encrypt small files of any type (MP4, MP3, JPG, PDF, DOCX), but when they are large it gives me an error of the type:

  

"Throwing OutOfMemoryError" Failed to allocate to 150835256 byte allocation with 25165824 free bytes and 121MB until OOM, max allowed footprint 435080136, growth limit 536870912 ""

the file is a 500mb video but it gives an error.

@RequiresApi(api = Build.VERSION_CODES.O)
public void Encriptar_Archivo() throws Exception {

//File archivo = new File(Ruta);
 //Path direccion = Paths.get(("/storage/emulated/0/pelicula.mp4"));
   File file = new File("/storage/emulated/0/pelicula.mp4");
   InputStream is = new BufferedInputStream(new FileInputStream(file));
   ByteArrayOutputStream buffer = new ByteArrayOutputStream();

   int nRead;
   byte[] data = new byte[1999368];

   while ((nRead = is.read(data, 0, data.length)) != -1) {
       buffer.write(data, 0, nRead);
   }

   buffer.flush();

   byte[] prueba = buffer.toByteArray();
   byte encriptado[];
   encriptado = Cifrar (prueba);

   decrypt (encriptado); //desencriptas el archivo


 System.out.println(encriptado);


}






 public static byte []  Cifrar(byte[] prueba) throws 
 UnsupportedEncodingException, NoSuchAlgorithmException, 
 NoSuchPaddingException, InvalidAlgorithmParameterException, 
 InvalidKeyException, BadPaddingException, IllegalBlockSizeException {



final MessageDigest md = MessageDigest.getInstance("md5");
final byte[] digestOfPassword = md.digest("OOAA2011".getBytes("utf-8"));
final byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
for (int j = 0, k = 16; j < 8;) {
    keyBytes[k++] = keyBytes[j++];
}
final SecretKey key = new SecretKeySpec(keyBytes, "DESede");
final IvParameterSpec iv = new IvParameterSpec(new byte[8]);
final Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS7Padding");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] result= cipher.doFinal(prueba);

return result;

}
@RequiresApi(api = Build.VERSION_CODES.O)
public static byte[] decrypt(byte[] message) throws Exception {
final MessageDigest md = MessageDigest.getInstance("md5");
final byte[] digestOfPassword = md.digest("OOAA2011".getBytes("utf-8"));
final byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
for (int j = 0, k = 16; j < 8;) {
    keyBytes[k++] = keyBytes[j++];
}
final SecretKey key = new SecretKeySpec(keyBytes, "DESede");
final IvParameterSpec iv = new IvParameterSpec(new byte[8]);
final Cipher decipher = Cipher.getInstance("DESede/ECB/PKCS7Padding");
decipher.init(Cipher.DECRYPT_MODE, key);

final byte[] plainText = decipher.doFinal(message);


//Path path = Paths.get("/storage/emulated/0/Ejemplo.docx");
// Files.write(path, plainText);
Files.write(new File("/storage/emulated/0/Ejemplo2.mp4").toPath(), plainText);

return plainText;
 }
    
asked by juanjo 18.05.2018 в 17:51
source

2 answers

1

And if you assign the size of the byte array in this way:

File file = new File("/storage/emulated/0/pelicula.mp4");
InputStream is = new BufferedInputStream(new FileInputStream(file));

Integer tam = ((Long)is.length()).intValue();
byte[] bytesFile = new byte[tam];
    
answered by 18.05.2018 в 18:59
0

You are trying to read the entire file and keep it in an array to encrypt it, it is normal for a 500MB file to leave you without memory.

What you have to do is read a certain amount of data (a few KB) encrypt them and save them in the destination file, and iterate the process, something like the following (note: I have not tried to compile it, there may be some Errata):

File file = new File("/storage/emulated/0/pelicula.mp4");
InputStream is = new BufferedInputStream(new FileInputStream(file));
Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS7Padding");
cipher.init(Cipher.ENCRYPT_MODE, key);
CipherOutputStream out = new CipherOutputStream(
       new FileOutputStream(fichero), cipher);
byte[] buffer = new byte[8192];
int count;
while ((count = is.read(buffer)) > 0) {
    out.write(buffer, 0, count);
}
    
answered by 18.05.2018 в 18:34