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;
}
}
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 :-( ");
}
}
}