Java 解密时出现错误的填充异常,但仍然有效

Java 解密时出现错误的填充异常,但仍然有效,java,encryption,cryptography,aes,Java,Encryption,Cryptography,Aes,我试图写一个程序,加密和解密的文本文件使用密码。它在加密时不会抛出任何错误,但在解密时会抛出一个错误的填充异常,但它仍然输出正确的文本,但最后会有额外的内容。我搜索了其他答案,但找不到解决方案。该程序通过编译成runnable jar并像java-jar文件名e/d(加密/解密)inputFile.txt outputFile.txt密码一样运行 提前谢谢 编辑: 这是我添加outputBuffer=cipher.doFinal(inputBuffer)的地方 样本输入: Exception:

我试图写一个程序,加密和解密的文本文件使用密码。它在加密时不会抛出任何错误,但在解密时会抛出一个错误的填充异常,但它仍然输出正确的文本,但最后会有额外的内容。我搜索了其他答案,但找不到解决方案。该程序通过编译成runnable jar并像java-jar文件名e/d(加密/解密)inputFile.txt outputFile.txt密码一样运行

提前谢谢

编辑:

这是我添加outputBuffer=cipher.doFinal(inputBuffer)的地方

样本输入:

Exception:
javax.crypto.BadPaddingException: Given final block not properly padded. Such issues can arise if a bad key is used during decryption.
        at java.base/com.sun.crypto.provider.CipherCore.unpad(Unknown Source)
        at java.base/com.sun.crypto.provider.CipherCore.fillOutputBuffer(Unknown Source)
        at java.base/com.sun.crypto.provider.CipherCore.doFinal(Unknown Source)
        at java.base/com.sun.crypto.provider.AESCipher.engineDoFinal(Unknown Source)
        at java.base/javax.crypto.Cipher.doFinal(Unknown Source)
        at FileEncryptorSkeleton.main(FileEncryptorSkeleton.java:183)
样本输出:

aaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazz
aaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazz
aaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazz
aaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazz
aaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazz
aaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazz
aaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazz
aaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazz
aaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazz
aaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazz

您反复调用
bytesRead=in.read(inputBuffer)
然后
cipher.update(inputBuffer)
。当到达输入文件的末尾时,只有部分
inputBuffer
被设置为新数据,其余部分是上一次读取的剩余数据,但您使用了所有数据。然后调用
cipher.doFinal(inputBuffer)
,它使用上次读取后留在缓冲区中的内容的另一个副本

在加密方面,这会导致重复加密最后几行中的某些数据(最多128字节)。解密时,这会导致调用
doFinal
,调用的数据实际上不是密文的最后一部分,因此出现“错误填充”异常

相反,请执行以下操作(为清晰起见,采用模错误处理):


PS:应用于一般数据(如“文本文档”)的ECB几乎总是不安全的;谷歌企鹅。只有128次迭代的PBKDF2不是很好,而盐含量恒定的PBKDF2是很差的。但这些都是安全问题,在这里是离题的。

您反复调用
bytesRead=in.read(inputBuffer)
然后
cipher.update(inputBuffer)
。当到达输入文件的末尾时,只有部分
inputBuffer
被设置为新数据,其余部分是上一次读取的剩余数据,但您使用了所有数据。然后调用
cipher.doFinal(inputBuffer)
,它使用上次读取后留在缓冲区中的内容的另一个副本

在加密方面,这会导致重复加密最后几行中的某些数据(最多128字节)。解密时,这会导致调用
doFinal
,调用的数据实际上不是密文的最后一部分,因此出现“错误填充”异常

相反,请执行以下操作(为清晰起见,采用模错误处理):


PS:应用于一般数据(如“文本文档”)的ECB几乎总是不安全的;谷歌企鹅。只有128次迭代的PBKDF2不是很好,而盐含量恒定的PBKDF2是很差的。但这些都是安全问题和离题。

请提供您看到错误的确切位置,以及随附的示例输入。我相信你一定看到了一个异常,请提供堆栈跟踪。你可能想看一看请不要破坏你的帖子。请提供你看到错误的确切位置以及所提供的附加示例输入。我相信你一定看到了一个异常,为它提供堆栈跟踪。你可能想看看,请不要破坏你的帖子。绝对传奇!我只使用ECB,因为分配要求我们使用ECB、CBC和默认IV以及随机IV创建单独的方法。绝对图例!我只使用ECB,因为分配要求我们使用ECB、CBC和默认IV以及随机IV创建单独的方法。
aaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazz
aaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazz
aaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazz
aaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazz
aaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazz
aaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazz
aaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazz
aaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazz
aaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazz
aaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazz
aaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazz
aaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazz
aaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazz
aaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazz
aaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazz
aaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazz
aaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazz
aaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazz
aaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazz
aaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazz
aaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazz
aaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazz
aaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazz
aaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzzaaaazzzz
bytesRead = in.read(inputBuffer);
while( bytesRead > 0 ){
    outputBuffer = cipher.update(inputBuffer, 0, readBytes); // only use the part read 
    out.write(outputBuffer);
    bytesRead = in.read(inputBuffer);
}
outputBuffer = cipher.doFinal(); // no data at all here, .update already processed it
out.write(outputBuffer);