adamhathcock / sharpcompress

SharpCompress is a fully managed C# library to deal with many compression types and formats.
MIT License
2.29k stars 480 forks source link

Cannot call ZipArchiveEntry.OpenEntryStream() multiple times with WinZipAes encrypted ZIP file #230

Closed dbaumber closed 7 years ago

dbaumber commented 7 years ago

When debugging an issue with not being able to open a stream to an entry in WinZipAes protected ZIP file, I found that if ZipArchiveEntry.OpenEntryStream() is called a second time, SharpCompress throws a CryptographicException with a message "The password did not match", which is thrown from PkwareTraditionalEncryptionData.ForRead(). More analysis shows that Header.CompressionMethod is changed from WinZipAes (correct value) to Deflate (wrong value) after GetCompressedStream() is called in ZipArchiveEntry.OpenEntryStream(). When OpenEntryStream() is called again, it thinks it is encrypted with PKWARE traditional encryption rather than WinZipAes, which fails.

I made a change to ZipArchiveEntry.OpenEntryStream() to save and restore the compression method which resolves this issue. I can provide this as a patch. This behavior has changed since 0.11, the previous version we used. OpenEntryStream() should be able to be called more than once since it returns a non-seekable stream, this allows for resetting the stream for a file entry back to the beginning of the entry.

adamhathcock commented 7 years ago

Please provide a pull request and maybe extent a test to test for it. Probably just an oversight.

dbaumber commented 7 years ago

I've submitted pull a request. I'll work on a test for it next. Would it be possible to get this fix into the 0.16 release? This is an important issue for us. Thanks!

adamhathcock commented 7 years ago

I can easily put out a patch version if things are simple enough.

dbaumber commented 7 years ago

It is a 4 line change in ZipArchiveEntry.OpenEntryStream(). It has no effect on anything else. I don't quite understand why the compression method changes but preserving it over the GetCompressedStream() call fixes our issue. We don't need a special patch version if the 0.16 release is coming in the next week or so.

adamhathcock commented 7 years ago

Put in 0.16.1