Unencrypting的难度:错误是BadPaddingException:给定最终块没有正确填充

时间:2016-06-03 18:22:59

标签: java encryption aes zipinputstream javax.crypto

尝试取消加密压缩文件。有些工作和其他工作没有。那些不工作的人在尝试关闭ZipInputStream时会出错。

这在用户计算机上创建文件时工作正常,但我想避免这种安全风险。我以为我通过最终删除文件来处理所有风险,但目睹了文件未被删除的情况。因此,我想完全避免这种可能性。使用Using streams to decrypt and unzip to limit memory usage?来获取我的代码。

我已经阅读了几个关于填充等的地方,但我承认我已经继承了这段代码,而且我还在学习曲线上。

final File file = new File(path, fileName);
Key key = new SecretKeySpec(secret, "AES");
final Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, key);
try (FileInputStream fis = new FileInputStream(file); CipherInputStream cis = new CipherInputStream(fis, cipher); ZipInputStream zis = new ZipInputStream(new BufferedInputStream(cis))) {
                ZipEntry entry;
                while ((entry = zis.getNextEntry()) != null) {

                    List<String> lines;
                    try ( ByteArrayOutputStream output = new ByteArrayOutputStream(2048)) {
                        int len;
                        while ((len = zis.read(buffer)) > 0) {
                            output.write(buffer, 0, len);
                        }
                        try (ByteArrayInputStream bais = new ByteArrayInputStream(output.toByteArray()); Reader reader = new InputStreamReader(bais)) {
                            lines = readFile(reader);
                        }
                    }
                    //Do something with lines of the file...

                }

            }

我得到的错误低于最后一行(try-with-resources块的结尾)。

java.io.IOException: javax.crypto.BadPaddingException: Given final block not properly padded
    at javax.crypto.CipherInputStream.close(CipherInputStream.java:321)
    at java.io.BufferedInputStream.close(BufferedInputStream.java:472)
    at java.io.PushbackInputStream.close(PushbackInputStream.java:379)
    at java.util.zip.InflaterInputStream.close(InflaterInputStream.java:227)
    at java.util.zip.ZipInputStream.close(ZipInputStream.java:265)

Caused by: javax.crypto.BadPaddingException: Given final block not properly padded
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:811)
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:676)
    at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:313)
    at javax.crypto.Cipher.doFinal(Cipher.java:1970)
    at javax.crypto.CipherInputStream.close(CipherInputStream.java:314)

我已经调试并完成了代码。抛出此错误的文件未加密并解压缩并正确读取。所有数据都被读出,&#34;线&#34;在各方面都是完整的。它只是没有关闭ZipInputStream。有什么想法吗?

1 个答案:

答案 0 :(得分:1)

我的问题是我正在解密,但在尝试解压缩之前没有先重写ByteArrayOutputStream。

我的代码已更正并正常工作:

public void decrypt(final byte[] secret, final File encryptedFile ) throws IOException {
        final ByteArrayOutputStream baos;
        try {
            final Cipher cipher = Cipher.getInstance("AES");
            cipher.init(Cipher.DECRYPT_MODE, modelEncryptor.getKey());
            try (FileInputStream fis = new FileInputStream(encryptedFile); CipherInputStream cis = new CipherInputStream(fis, cipher)) {
                baos = new ByteArrayOutputStream();
                byte[] buff = new byte[8];
                int numRead = cis.read(buff);
                while (numRead != -1) {
                    baos.write(buff, 0, numRead); //I was trying to combine this write with the unzipping write.
                    numRead = cis.read(buff);
                }
            }
        } catch (Exception ex) {
            throw new IOException("Unable to decrypt " + encryptedFile, ex);
        }

        try (ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); ZipInputStream zipIn = new ZipInputStream(new BufferedInputStream(bais))) {
            ZipEntry entry;
            while ((entry = zipIn.getNextEntry()) != null) {
                int BUFFER = 2048;
                ByteArrayOutputStream fos = new ByteArrayOutputStream(2048);
                try (BufferedOutputStream dest = new BufferedOutputStream(fos, BUFFER)) {
                    int count;
                    byte data[] = new byte[BUFFER];
                    while ((count = zipIn.read(data, 0, BUFFER)) != -1) {
                        dest.write(data, 0, count);
                    }
                    dest.flush();
                }
                final List<String> lines = Arrays.asList(fos.toString().split("\r\n"));
                //Do something with lines...
            }
        }
        baos.close();
    }

通过将解密与解压缩分开,现在一切都很好。 希望有一天能帮助别人。

P.S。我在加密方面没有改变任何东西。