I use the BouncyCastle provider to encrypt files using "AES / GCM / NoPadding" as a conversion. It worked for a large number of small files. But with large files, I get an exception:
javax.crypto.AEADBadTagException: tag mismatch!
Here is the code I use for encryption:
try (DataOutputStream os = new DataOutputStream(new FileOutputStream(encryptedFile))) {
os.writeInt(CURRENT_ENCRYPTION_FILE_VERSION);
os.writeInt(CURRENT_RSA_KEY_VERSION);
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(128);
SecretKey aesKey = keyGenerator.generateKey();
os.write(doRsaTransformation(aesKey.getEncoded(), publicRsaKey, Cipher.ENCRYPT_MODE));
SecureRandom sr = new SecureRandom();
byte[] iv = new byte[16];
sr.nextBytes(iv);
os.write(doRsaTransformation(iv, publicRsaKey, Cipher.ENCRYPT_MODE));
doAesFileEncryption(fileToEncrypt, aesKey, iv, os);
} catch (NoSuchAlgorithmException | BadPaddingException | IllegalBlockSizeException | InvalidKeyException | NoSuchPaddingException | IOException | InvalidAlgorithmParameterException ex) {
throw new EncryptionException(ex);
}
private void doAesFileEncryption(File fileToEncrypt, SecretKey aesKey, byte[] iv, OutputStream os) {
Cipher aesCipher = Cipher.getInstance("AES/GCM/NoPadding");
aesCipher.init(Cipher.ENCRYPT_MODE, aesKey, new GCMParameterSpec(128, iv));
byte[] block = new byte[1024];
int i;
try (FileInputStream fis = new FileInputStream(fileToEncrypt)) {
while ((i = fis.read(block)) != -1) {
byte[] encryptedBlock = aesCipher.update(block, 0, i);
if (encryptedBlock != null) {
os.write(encryptedBlock);
}
}
byte[] encryptedFinal = aesCipher.doFinal();
if (encryptedFinal != null) {
os.write(encryptedFinal);
}
}
}
Here is the code I use to decrypt:
Cipher aesCipher = Cipher.getInstance("AES/GCM/NoPadding");
aesCipher.init(Cipher.DECRYPT_MODE, aesKey, new GCMParameterSpec(128, iv));
byte[] block = new byte[1073741824];
int i;
try (FileOutputStream fos = new FileOutputStream(decryptedFile)) {
while ((i = is.read(block)) != -1) {
byte[] decryptedBlock = aesCipher.update(block, 0, i);
if (decryptedBlock != null) {
fos.write(decryptedBlock);
}
}
byte[] decryptedFinal = aesCipher.doFinal();
if (decryptedFinal != null) {
fos.write(decryptedFinal);
}
}
UPDATE:
I have been trying to figure this out for several days now. Fortunately, I at least figured out how to decrypt a file that I desperately need!
, Java 7 51. ( , , .) ( ), Java 8. , . Java 7, .
? , Java 8 , Java 7.
Java, Java, ? , ?
! !