如何解压使用pkAES-256加密和Deflate压缩的zip文件?

huangapple go评论103阅读模式
英文:

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

问题

我需要使用Java解压缩带有以下信息的压缩和密码保护的zip文件:

方法:pkAES-256 Deflate

特征:0xD StrongCrypto:加密StrongCrypto

我尝试使用zip4j,但它总是给我这个堆栈跟踪:

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

有人知道如何处理这种加密吗?我只能使用7zip打开这些文件 - 但我需要用Java来做。

谢谢你的帮助。

英文:

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.

答案1

得分: 0

ZIP文件格式,至少是普遍被理解并且被许多库支持的那种,只支持一种加密方式;它被称为“ZipCrypto”,它的质量存疑(它并非完全破解,但很容易陷入这样的情况:有人可能会弄清楚不应该能够读取该ZIP文件的情况。例如,尝试许多密码非常容易,因此,如果密码是一个简单的词典单词,它基本上是无用的)。这是当你在命令行上运行zip -c时得到的加密结果,几乎适用于每个发行版的“zip”可执行文件。

WinZip自行添加了ZIP格式的一个扩展,称为StrongCrypto,它基于AES-256。听起来你有这个。

zip基本上是公共领域的(这有点复杂;PKWare公司基本上拥有它的各个部分,但尽管如此,例如你的Linux发行版中的/bin/unzip命令是完全开源的,从法律上讲,zip的命运有些棘手解释)... 因此,当WinZip自行向zip概念添加功能时,这是相当愚蠢的:开源社区和PKWare都不会同意这种随意的升级,因此在很长一段时间内,这些以“.zip”结尾的“基于WinZip的强加密zip文件”实际上并不是zip文件,如果这让人感到困惑,责任完全在于WinZip公司。你现在拥有的并不是一个zip文件,即使看起来像

然而,此后至少WinZip和PKWare达成了协议,它们可以解密彼此的更强加密选项。然而,开源社区大部分已经撇清了关系,不认为这些强加密选项是“zip文件”。这就解释了为什么你所使用的库 无法解密这个文件,而且可能永远无法解密。

因此,由于PKWare和WinZip的把戏造成的这种混乱:如果你想要加密一个zip文件,我 强烈 建议你不要使用zip内置的东西(无论是糟糕的ZipCrypto,还是支持不好的StrongCrypto),而是像正常情况下一样进行压缩,然后加密生成的文件(然后不要将该文件命名为foo.zip,因为它不再是一个zip文件。foo.zip.enc可能是一个更好的名称)。

如果你被困在这个问题上,而且没有改变要发送文件的可能性,你需要使用7zip。7zip是开源的,可能可以解密这个文件,而大多数开源的“zip”库则不能。一个大问题是我所知道的并没有一个纯Java的7zip实现。确实存在7zip-binding项目,它将工作转交给一个C库,这意味着你需要在你的Java项目中有一个所谓的“本地”文件(在Windows上是DLL,在Linux上是.SO文件,在Mac上是.JNILIB文件),你需要为每个你想要支持的架构/操作系统组合都有一个这样的文件。有点痛苦,它破坏了Java的“编写一次,随处运行”的承诺,但这是你必须做的。这个网站看起来已经够老了,可以买啤酒了,但据我所知它正在维护,所以还好。但是,说真的,不要使用zip的内置加密功能,它很糟糕。尽量避免使用它。

注意:7zip能够实现这一点的原因是观点的不同:支持普通zip的开源社区努力保持其简单性,以确保尽可能多的平台可以实现,这可能是为什么有各种各样的全Java zip实现。7zip试图提供强大的支持,代价是让7zip在各个平台上移植变得更加困难,这可能就是为什么没有一个全Java的7zip实现,只有一个绑定。因此,7zip愿意尝试解密这个WinZip的东西,而普通的zip则不会。

英文:

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, e.g. 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.

huangapple
  • 本文由 发表于 2020年8月18日 21:10:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/63469370.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定