我一直在使用BouncyCastle的提供程序来使用" AES / GCM / NoPadding"来加密文件。作为转型。它适用于许多较小的文件。但是,对于较大的文件,我得到了例外:
javax.crypto.AEADBadTagException:标签不匹配!
以下是我用来加密的代码:
try (DataOutputStream os = new DataOutputStream(new FileOutputStream(encryptedFile))) {
os.writeInt(CURRENT_ENCRYPTION_FILE_VERSION);
os.writeInt(CURRENT_RSA_KEY_VERSION);
// Generate a new random symmetric key for the AES encryption cipher
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(128);
SecretKey aesKey = keyGenerator.generateKey();
// Write the RSA encrypted AES key to the file
os.write(doRsaTransformation(aesKey.getEncoded(), publicRsaKey, Cipher.ENCRYPT_MODE));
// Generate an initialization vector (IV)
SecureRandom sr = new SecureRandom();
byte[] iv = new byte[16];
sr.nextBytes(iv);
// Write the RSA encrypted IV to the file
os.write(doRsaTransformation(iv, publicRsaKey, Cipher.ENCRYPT_MODE));
// Write the encrypted file
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);
}
}
}
以下是我用来解密的代码:
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);
}
}
更新 我一直在努力解决这个问题。幸运的是,我至少想出了如何解密我迫切需要的文件!
该文件在运行Java 7更新51的服务器上进行了加密。(我知道我不能保持最新状态。)现在我试图在我的本地解密它运行Java 8的计算机(和其他本地计算机)。对于较大的文件,我总是得到上述异常,而不是较小的文件。如果我用Java 7解密大文件,那么它会解密而没有错误。
预计会出现这种情况吗?在我看来,Java 8应该能够解密用Java 7加密的大型文件。
如果我不能依赖使用旧版Java加密的较新版本的Java解密文件,那么我该如何继续前进?我是否必须使用旧版本解密所有文件,以便我可以使用新版本加密它们?
非常感谢!非常感谢任何帮助!