Search code examples
javaencryptionaes

Encryption decryption AES for all type of file in java


how to modify this AES encryption code so that it can encrypt and decrypt any type of file (pdf, docx....), because when I decrypt a pdf file or other I don't get the original file.

public EncryptData(File originalFile, File encrypted, SecretKeySpec secretKey, String cipherAlgorithm) throws IOException, GeneralSecurityException{
    this.cipher = Cipher.getInstance(cipherAlgorithm);      
    encryptFile(getFileInBytes(originalFile), encrypted, secretKey);
}

public void encryptFile(byte[] input, File output, SecretKeySpec key) throws IOException, GeneralSecurityException {
    this.cipher.init(Cipher.ENCRYPT_MODE, key);
    writeToFile(output, this.cipher.doFinal(input));
}
public SecretKeySpec getSecretKey(String filename, String algorithm) throws IOException{
    byte[] keyBytes = Files.readAllBytes(new File(filename).toPath());
    return new SecretKeySpec(keyBytes, algorithm);
}

public static void main(String[] args) throws IOException, GeneralSecurityException, Exception{
    StartEncryption startEnc = new StartEncryption();
    File originalFile = new File("file.docx");
    File encryptedFile = new File("EncryptedFiles/encryptedFile");
    new EncryptData(originalFile, encryptedFile, startEnc.getSecretKey("OneKey/secretKey", "AES"), "AES");
}
public DecryptData(File encryptedFileReceived, File decryptedFile, SecretKeySpec secretKey, String algorithm) throws IOException, GeneralSecurityException {
    this.cipher = Cipher.getInstance(algorithm);
    decryptFile(getFileInBytes(encryptedFileReceived), decryptedFile, secretKey);
}

public void decryptFile(byte[] input, File output, SecretKeySpec key) throws IOException, GeneralSecurityException {
    this.cipher.init(Cipher.DECRYPT_MODE, key);
    writeToFile(output, this.cipher.doFinal(input));
}
public SecretKeySpec getSecretKey(String filename, String algorithm) throws IOException{
    byte[] keyBytes = Files.readAllBytes(new File(filename).toPath());
    return new SecretKeySpec(keyBytes, algorithm);
}

public static void main(String[] args) throws IOException, GeneralSecurityException, Exception{
    StartDecryption startEnc = new StartDecryption();
    
    File encryptedFileReceived = new File("EncryptedFiles/encryptedFile");
    File decryptedFile = new File("DecryptedFiles/decryptedFile");
    new DecryptData(encryptedFileReceived, decryptedFile, startEnc.getSecretKey("DecryptedFiles/SecretKey", "AES"), "AES");
    
}

Solution

  • As some important information regarding your source code is missing (method writeToFile, no information about the cipherAlgorithm, no information about the used key) your code is not executable.

    Therefore I'm providing a sample program to encrypt and decrypt any kind of files using the AES mode ECB.

    Security warning: do NOT use AES ECB Mode in production because it is UNSECURE ! It's better to use a mode like AES GCM.

    Provide the filenames for the original file (plaintextfile), the encrypted file (ciphertextfile) and the decrypted file (decryptedfile) and run the program - the decrypted file is equal to the original file.

    I'm using a static key (32 byte/256 bit key length) for this example - to run this program you need the unlimited crypto policies enabled on your Java system.

    That's the result:

    https://stackoverflow.com/questions/62883618/encryption-decryption-aes-for-all-type-of-file-in-java
    AES ECB Stream Encryption
    * * * WARNING Do NOT use AES ECB mode in production as it is UNSECURE ! * * *
    file used for encryption: plaintext.pdf
    created encrypted file  : plaintext.enc
    created decrypted file  : plaintext_decrypted.pdf
    AES ECB Stream Encryption ended
    

    The code:

    import javax.crypto.BadPaddingException;
    import javax.crypto.Cipher;
    import javax.crypto.IllegalBlockSizeException;
    import javax.crypto.NoSuchPaddingException;
    import javax.crypto.spec.SecretKeySpec;
    import java.io.*;
    import java.security.InvalidKeyException;
    import java.security.NoSuchAlgorithmException;
    
    public class AES_ECB_Stream {
        public static void main(String[] args) throws IOException, NoSuchPaddingException, NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException, InvalidKeyException {
            System.out.println("https://stackoverflow.com/questions/62883618/encryption-decryption-aes-for-all-type-of-file-in-java");
            System.out.println("AES ECB Stream Encryption");
            System.out.println("* * * WARNING Do NOT use AES ECB mode in production as it is UNSECURE ! * * *");
            String plaintextFilename = "plaintext.pdf";
            String ciphertextFilename = "plaintext.enc";
            String decryptedtextFilename = "plaintext_decrypted.pdf";
            byte[] key = "12345678901234561234567890123456".getBytes("UTF-8"); // 32 byte = 256 bit key length
            encryptWitEcb(plaintextFilename, ciphertextFilename, key);
            decryptWithEcb(ciphertextFilename, decryptedtextFilename, key);
            System.out.println("file used for encryption: " + plaintextFilename);
            System.out.println("created encrypted file  : " + ciphertextFilename);
            System.out.println("created decrypted file  : " + decryptedtextFilename);
            System.out.println("AES ECB Stream Encryption ended");
        }
    
        public static void encryptWitEcb(String filenamePlain, String filenameEnc, byte[] key) throws IOException,
                NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
                IllegalBlockSizeException, BadPaddingException {
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
            SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
            try (FileInputStream fis = new FileInputStream(filenamePlain);
                 BufferedInputStream in = new BufferedInputStream(fis);
                 FileOutputStream out = new FileOutputStream(filenameEnc);
                 BufferedOutputStream bos = new BufferedOutputStream(out)) {
                byte[] ibuf = new byte[1024];
                int len;
                while ((len = in.read(ibuf)) != -1) {
                    byte[] obuf = cipher.update(ibuf, 0, len);
                    if (obuf != null)
                        bos.write(obuf);
                }
                byte[] obuf = cipher.doFinal();
                if (obuf != null)
                    bos.write(obuf);
            }
        }
    
        public static void decryptWithEcb(String filenameEnc, String filenameDec, byte[] key) throws IOException,
                NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
                IllegalBlockSizeException, BadPaddingException {
            try (FileInputStream in = new FileInputStream(filenameEnc);
                 FileOutputStream out = new FileOutputStream(filenameDec)) {
                byte[] ibuf = new byte[1024];
                int len;
                Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
                SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
                cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
                while ((len = in.read(ibuf)) != -1) {
                    byte[] obuf = cipher.update(ibuf, 0, len);
                    if (obuf != null)
                        out.write(obuf);
                }
                byte[] obuf = cipher.doFinal();
                if (obuf != null)
                    out.write(obuf);
            }
        }
    }