开发者

How to decompress an AES-256 Encrypted zip files?

I am developing an android application which requires to decompres开发者_StackOverflows an AES-256 encrypted zip files, is there any libraries out there that I can use to accomplish that?

I am greatly appreciative of any guidance or help.


zip4j, java library to handle Zip files (Open source, Apache License v2.0).

http://www.lingala.net/zip4j/

  • Create, Add, Extract, Update, Remove files from a Zip file
  • Read/Write password protected Zip files
  • Supports AES 128/256 Encryption
  • Supports Standard Zip Encryption

You can download binary, sources and examples.


I ended up using an external library at http://code.google.com/p/winzipaes/

it's limited to compression/decompression Zip files encrypted with AES-256 ONLY

but at least it fits my need.


It depends on you encoding of encrypted zip files. Be more specific please. If its compress then encrypt then you decompress then decrypt the file using java.util.zip.GZIPInputStream


As far as I remember AES encrypted ZIP files were introduced some years the first time by WinZip. On the WinZip home page there is a detailed explanation how the AES encrypted ZIP files differs from a standard ZIP file:

http://www.winzip.com/aes_info.htm


I am working on a normal JRE. Using http://www.lingala.net/zip4j/ the following code works to decrypt a zip file:

ZipFile zipFile = new ZipFile(zipFile);
zipFile.setPassword(password);
for (Object fileHeaderObj : zipFile.getFileHeaders()) {
  FileHeader fileHeader = (FileHeader) fileHeaderObj;
  String fileName = fileHeader.getFileName();
  ZipInputStream zipIn = zipFile.getInputStream(fileHeader);
  // do whatever with the input stream
}


I face a similar problem and searched a lot and tested all these solutions but they didn't help me. Finally, I found a solution and I want to share it here maybe it can help others.

In my case, I have a AES-256 Encrypted zip file.

When I used the last version of zip4j, I faced this exception:

Zip4j does not support Strong Encryption

zip4j code:

    net.lingala.zip4j.ZipFile zipFile = new ZipFile("sourceAddress", "password".toCharArray());
    zipFile.extractAll("destinationAddress");

After that I tested winzipaes and I faced this error:

extra field is of length 0 - this is probably not a WinZip AES encrypted entry

winzipaes code:

    final File dbFile = new File("destinationFile");
    AesZipFileDecrypter ze = null;
    try {
        ze = new AesZipFileDecrypter(new File("sourceAddress"), new AESDecrypterBC());
        ExtZipEntry entry = ze.getEntry(dbFile.getName());
        ze.extractEntry(entry, dbFile, "password");
    } catch (DataFormatException | IOException e) {
        e.printStackTrace();
    } finally {
        if (ze != null) {
            try {
                ze.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

Finally, I find sevenzipjbind and it works for me.

Final code:

    RandomAccessFile randomAccessFile = null;
    IInArchive inArchive = null;
    try {
        randomAccessFile = new RandomAccessFile(fileAddress, "r");
        inArchive = SevenZip.openInArchive(null, // autodetect archive type
                new RandomAccessFileInStream(randomAccessFile));

        // Getting simple interface of the archive inArchive
        ISimpleInArchive simpleInArchive = inArchive.getSimpleInterface();

        System.out.println("   Hash   |    Size    | Filename");
        System.out.println("----------+------------+---------");

        for (ISimpleInArchiveItem item : simpleInArchive.getArchiveItems()) {
            final int[] hash = new int[] { 0 };
            if (!item.isFolder()) {
                ExtractOperationResult result;

                result = item.extractSlow(new ISequentialOutStream() {
                    public int write(byte[] data) throws SevenZipException {
                        InputStream myInputStream = new ByteArrayInputStream(data);

                        try {
                            byte[] buffer = new byte[myInputStream.available()];
                            myInputStream.read(buffer);
                            File targetFile = new File(destinationAddress + item.getPath());
                            OutputStream outStream = new FileOutputStream(targetFile);
                            outStream.write(buffer);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }

                        return data.length; // Return amount of consumed data
                    }
                },password);

                if (result == ExtractOperationResult.OK) {
                    System.out.printf("%9X | %s%n",
                            hash[0], item.getPath());
                } else {
                    System.err.println("Error extracting item: " + result);
                }
            }
        }
    } catch (Exception e) {
        System.err.println("Error occurs: " + e);
    } finally {
        if (inArchive != null) {
            try {
                inArchive.close();
            } catch (SevenZipException e) {
                System.err.println("Error closing archive: " + e);
            }
        }
        if (randomAccessFile != null) {
            try {
                randomAccessFile.close();
            } catch (IOException e) {
                System.err.println("Error closing file: " + e);
            }
        }
    }


I don't have tested it yet, but some time ago I found this.

I hope it can help you

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜