简体   繁体   中英

How to decompress an pkAES-256 Deflate encrypted zip files?

I need to unzip zip files with Java which are compressed and password secured with following information:

Method: pkAES-256 Deflate

Chraracteristics: 0xD StrongCrypto: Encrypt StrongCrypto

I tried to use zip4j but it always gives me this stacktrace:

net.lingala.zip4j.exception.ZipException: java.io.IOException: java.util.zip.DataFormatException: invalid code lengths set
    at net.lingala.zip4j.tasks.AsyncZipTask.performTaskWithErrorHandling(AsyncZipTask.java:51)
    at net.lingala.zip4j.tasks.AsyncZipTask.execute(AsyncZipTask.java:38)
    at net.lingala.zip4j.ZipFile.extractFile(ZipFile.java:494)
    at net.lingala.zip4j.ZipFile.extractFile(ZipFile.java:460)
    at Main.main(Main.java:29)
Caused by: java.io.IOException: java.util.zip.DataFormatException: invalid code lengths set
    at net.lingala.zip4j.io.inputstream.InflaterInputStream.read(InflaterInputStream.java:55)
    at net.lingala.zip4j.io.inputstream.ZipInputStream.read(ZipInputStream.java:141)
    at net.lingala.zip4j.io.inputstream.ZipInputStream.read(ZipInputStream.java:121)
    at net.lingala.zip4j.tasks.AbstractExtractFileTask.unzipFile(AbstractExtractFileTask.java:82)
    at net.lingala.zip4j.tasks.AbstractExtractFileTask.extractFile(AbstractExtractFileTask.java:64)
    at net.lingala.zip4j.tasks.ExtractFileTask.executeTask(ExtractFileTask.java:39)
    at net.lingala.zip4j.tasks.ExtractFileTask.executeTask(ExtractFileTask.java:21)
    at net.lingala.zip4j.tasks.AsyncZipTask.performTaskWithErrorHandling(AsyncZipTask.java:44)
    ... 4 more
Caused by: java.util.zip.DataFormatException: invalid code lengths set
    at java.util.zip.Inflater.inflateBytes(Native Method)
    at java.util.zip.Inflater.inflate(Inflater.java:259)
    at net.lingala.zip4j.io.inputstream.InflaterInputStream.read(InflaterInputStream.java:45)
    ... 11 more

Does anybody knows how to deal with such an encryption? I can only open these files with 7zip - but I need to do that with Java.

Thank you for your help.

The ZIP file format, at least, the one that is universally understood and supported by tons of libraries, only supports one kind of encryption; it is called 'ZipCrypto', it is of dubious quality (it's not completely broken, but it's rather easy to end up in a scenario where someone who shouldn't be able to read that zip file will figure it out. It is for example quite easy to try tons of passwords, so if the password is a simple dictionary word, it's mostly useless). This is the crypto you get when you run zip -c on the command line for just about every distribution of the 'zip' executable.

WinZip added, all on its own, an extension to the ZIP format called StrongCrypto which is AES-256 based. It sounds like you have that.

zip is more or less public domain (it's tricky; PKWare as a company more or less owns various parts of it, but nevertheless, eg the /bin/unzip command in your linux distro is fully open source, legally the fate of zip is somewhat tricky to explain)... so when winzip, on its own, just adds features to the zip concept, that was quite idiotic: Neither the open source community at large, nor PKWare, would agree to this random flyby upgrade, so for a long while, these 'WinZip based strongcrypto zip files that end in.zip' just weren't zip files, and if that's confusing, the blame falls entirely on WinZip, Inc.'s shoulders. What you have just isnt a zip file, even if it looks like one .

However, since then, at least WinZip and PKWare now reached an agreement and they can decrypt each other's stronger crypto offerings. However, the open source community has mostly washed its hands and doesn't consider these strongcrypto options as 'zip files'. That explains why the library you have cannot decrypt this file , and probably never will.

Thus, because of this mess entirely due to PKWare and WinZip's shenanigans: if you want to encrypt a zip file, I STRONGLY suggest you don't use zip's built in stuff (neither ZipCrypto which is bad, nor StrongCrypto which is badly supported), but to just zip as normal with no encryption, and then encrypt the resulting file (and then don't name that file foo.zip , as it is no longer a zip file. foo.zip.enc would be a better name).

If you're stuck on this, and there is no possibility to change the format of the file being sent, you need 7zip. 7zip is open source and can probably decrypt this file, whereas most open source 'zip' libraries can't. A big problem is that there is no all-java 7zip impl that I'm aware of. There is the 7zip-binding project , which just farms out the work to a C library, which means you need a so-called 'native' file with your java project (a DLL on windows, a.SO file on linux, and a.JNILIB file on mac), and you need one such file for every architecture/OS combo you want to support. Kinda painful, it ruins the 'write once run anywhere' promise of java, but it's what you'd have to do. The site looks like it's old enough to order beers, but as far as I know it is being maintained, so there's that. But, seriously, don't use zip's built in encryption stuff, it sucks. Try to avoid it.

NB: The reason 7zip can do it is difference of opinion: the open source communities supporting plain zip endeavour to keep it simple to ensure as many platforms can do it, which is probably why there are various all-java zip impls around. 7zip tries to go for awesome support, at the cost of making it a lot harder to port 7zip around, which is probably why there isn't an all-java 7zip impl, only a binding. As a consequence, 7zip is willing to try to figure out how to decrypt this winzip stuff, plain zip isn't.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM