Chiffrer un gros fichier avec AES en utilisant JAVA

j'ai testé mon code avec des fichiers de moins de 10mb, 100mb, 500mb et le cryptage fonctionne. Cependant, j'ai des problèmes avec les fichiers supérieurs à 1 Go. J'ai généré un gros fichier (environ 2 Go) et je veux le chiffrer avec AES en utilisant JAVA, mais je suis en train d'exécuter cette erreur:

"Exception dans le fil" main " java.lang.OutOfMemoryError: Java heap space "

j'ai essayé d'augmenter la mémoire disponible en utilisant-Xmx8G, mais pas de dés. Une partie de mon code est le suivant

    File selectedFile = new File("Z:dummy.txt");         
    Path path = Paths.get(selectedFile.getAbsolutePath());       
    byte[] toencrypt = Files.readAllBytes(path);       
    byte[] ciphertext = aesCipherForEncryption.doFinal(toencrypt);
    FileOutputStream fos = new FileOutputStream(selectedFile.getAbsolutePath());
    fos.write(ciphertext);
    fos.close();

pour autant que je sache, la raison pour laquelle il se comporte de cette façon, c'est qu'il essaie de lire le fichier entier en une fois, de le chiffrer, et de le stocker dans un autre tableau de octets au lieu de le mettre en mémoire tampon et de le diffuser. Quelqu'un peut m'aider avec un peu de code conseils?

je suis un débutant au codage, donc je ne sais pas vraiment beaucoup, toute aide sera appréciée.

6
demandé sur halcyondayz 2015-12-24 06:53:43

2 réponses

N'essayez même pas de lire des fichiers entiers en mémoire. Crypter un tampon à la fois. Il suffit de faire la boucle de copie standard avec un CipherOutputStream convenablement initialisé enroulé autour du FileOutputStream . Vous pouvez l'utiliser pour tous les fichiers, pas besoin de faire d'un cas particulier. Utiliser un tampon de 8k ou plus.

MODIFIER La "copie standard en boucle" en Java, comme suit:

byte[] buffer = new byte[8192];
int count;
while ((count = in.read(buffer)) > 0)
{
    out.write(buffer, 0, count);
}

où, dans ce cas out = new CipherOutputStream(new FileOutputStream(selectedFile), cipher) .

11
répondu user207421 2015-12-24 06:41:48

vous pouvez également simplifier le processus encore plus en utilisant Encryptor4j: https://github.com/martinwithaar/Encryptor4j

File srcFile = new File("original.zip");
File destFile = new File("original.zip.encrypted");
String password = "mysupersecretpassword";
FileEncryptor fe = new FileEncryptor(password);
fe.encrypt(srcFile, destFile);

cette bibliothèque utilise le cryptage en continu de sorte qu'il ne causera pas OutOfMemoryError , même avec de gros fichiers. Aussi, au lieu d'utiliser des mots de passe, vous pouvez utiliser votre propre Key .

consultez l'exemple sur la page Github ici: https://github.com/martinwithaar/Encryptor4j#file-encryption

3
répondu whitebrow 2016-09-19 19:35:39