当前位置:  开发笔记 > 编程语言 > 正文

我得到javax.crypto.AEADBadTagException:标签不匹配!使用AES/GCM/NoPadding解密大文件时

如何解决《我得到javax.crypto.AEADBadTagException:标签不匹配!使用AES/GCM/NoPadding解密大文件时》经验,为你挑选了0个好方法。

我一直在使用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解密文件,那么我该如何继续前进?我是否必须使用旧版本解密所有文件,以便我可以使用新版本加密它们?

非常感谢你!任何帮助是极大的赞赏!

推荐阅读
路人甲
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有