Search code examples
javaencryptionaes

Encrypt and decrypt large file with AES


I am trying to encrypt a large file with AES, then decrypt it and compare with the original.

This class summarizes the work. It works OK for .txt files, but NOT for .mp3, .pdf and so on.

Help will be very appreciated.

import java.io.FileInputStream;
import java.io.FileOutputStream;

public class LargeFileEncryptionTest7 {

    protected static String FOLDER_PATH = "C:/temp/";
    protected static String FILE = "some-large-file";
    protected static String EXT = ".mp3"; //Works for .txt, but not for .mp3 or .pdf

    public static void main(String[] args) throws Exception {

        //Load file to encrypt
        byte[] largeFileBytes = loadFile(FOLDER_PATH + FILE + EXT);
        String largeFileString = new String(largeFileBytes);

        //Encrypt file with AES
        AESUtils aesUtils = new AESUtils();
        byte[] secretKey = aesUtils.generateSecretKey();
        aesUtils.setSecretKey(secretKey);
        byte[] largeFileEncBytes = aesUtils.encrypt(largeFileString);

        //Save encrypted file
        saveFile(largeFileEncBytes, FOLDER_PATH + FILE + "-encrypted" + EXT);

        //Load encrypted file
        byte[] largeFileEncBytesToCheck = loadFile(FOLDER_PATH + FILE + "-encrypted" + EXT);

        //Decrypt file      
        byte[] largeFileBytesToCheck = aesUtils.decrypt(largeFileEncBytesToCheck);
        String largeFileStringToCheck = new String(largeFileBytesToCheck);

        //Save decrypted file
        saveFile(largeFileBytesToCheck, FOLDER_PATH + FILE + "-decrypted" + EXT);

        //Check strings
        //System.out.println("Original content: " + largeFileStringToCheck);
        if (largeFileStringToCheck.equals(largeFileString)) {
            System.out.println("OK  :-) ");
        } else {
            System.out.println("KO  :-( ");
        }                       
    }

    private static void saveFile(byte[] bytes, String fileName) throws Exception {
        FileOutputStream fos = new FileOutputStream(fileName);
        fos.write(bytes);
        fos.close();
    }

    private static byte[] loadFile(String fileName) throws Exception {
        FileInputStream fis = new FileInputStream(fileName);
        int numBtyes = fis.available();
        byte[] bytes = new byte[numBtyes];
        fis.read(bytes);
        fis.close();
        return bytes;
    }

}

Solution

  • In case someone is interested I put here final solution.

    It is inspired in some of the comments people done. Mainly avoid the use of Strings and work with byte[]:

    import java.nio.file.Files;
    import java.nio.file.Paths;
    import java.util.Arrays;
    
    import javax.crypto.Cipher;
    import javax.crypto.KeyGenerator;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.SecretKeySpec;
    
    public class LargeFileEncryptionTest11 {
    
        private static final String FOLDER_PATH = "C:/temp/";
        private static final String FILE = "some-large-file";
        private static final String EXT = ".pdf";
    
        private static final String ENCRYPTION_ALGORITHM = "AES";
        private static final int KEY_SIZE = 128; // 192 and 256 bits may not be available
    
        public static void main(String[] args) throws Exception {
            //Common stuff to encrypt/decrypt
            KeyGenerator kgen = KeyGenerator.getInstance(ENCRYPTION_ALGORITHM);
            kgen.init(KEY_SIZE); 
            SecretKey skey = kgen.generateKey();
            byte[] secretKey = skey.getEncoded();
            SecretKeySpec skeySpec = new SecretKeySpec(secretKey, ENCRYPTION_ALGORITHM);
            Cipher cipher = Cipher.getInstance(ENCRYPTION_ALGORITHM);
    
            //Load file to encrypt
            byte[] largeFileBytes = Files.readAllBytes(Paths.get(FOLDER_PATH + FILE + EXT));
    
            //Encrypt file
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
            byte[] largeFileEncBytes = cipher.doFinal(largeFileBytes);
    
            //Save encrypted file
            Files.write(Paths.get(FOLDER_PATH + FILE + "-encrypted" + EXT), largeFileEncBytes);
    
            //Load encrypted file
            byte[] largeFileEncBytesToCheck = Files.readAllBytes(Paths.get(FOLDER_PATH + FILE + "-encrypted" + EXT));
    
            //Decrypt file      
            cipher.init(Cipher.DECRYPT_MODE, skeySpec);
            byte[] largeFileBytesToCheck = cipher.doFinal(largeFileEncBytesToCheck);
    
            //Save decrypted file
            Files.write(Paths.get(FOLDER_PATH + FILE + "-decrypted" + EXT), largeFileBytesToCheck);
    
            //Compare results
            if (Arrays.equals(largeFileBytes, largeFileBytesToCheck)) {
                System.out.println("OK  :-) ");
            } else {
                System.out.println("KO  :-( ");
            }                       
        }
    
    }