We discussed adding support for the traditional zip encryption algorithm a
while back. IIRC the concensus was loosely against it since it's so weak
and we don't want to mislead people.

Since then I can add two points.

First, I heard from someone who said that she has to use the traditional
encryption algorithm for legal reasons. To be more precise she don't have
to use the traditional zip encryption algorithm specifically - she has to
use some form of encryption and for various reasons (e.g., ancient embedded
systems that can't be updated) this is the best she can do. It's enough to
satisfy the legal requirement that the data not be sent in plaintext and
her exposure is limited since it's only used during the brief window when
the embedded systems make a dialup connection to the central server.

In any case it's someone with a good use case for why she needs to continue
using the traditional algorithm.

Second, I've been looking at the strong encryption algorithms (WinZip and
the un-distributable PKWare) and they'll need some way to insert encryption
and decryption into the ZIP streams. The traditional approach may
illustrate problems we can expect with WinZip strong encryption.

My approach is to create two Filter classes -
TraditionalZipEncryptionInputStream and
TraditionalZipEncryptionOutputStream - and inject them at the lowest level.

There are two problems that prevent this from being completely transparent.

First, the ciphertext is precisely 12 bytes larger than the plaintext due
to the presence of an encrypted salt. I know that ZipEntry has a
'compressed size' field that's used with reading and skipping the actual
stream but I don't know if the decompression logic uses an internal EOF
marker or if it uses the number of bytes. This might cause problems and I
don't want to make any assumptions.

Second, the algorithm requires the CRC of the original data. The last byte
of the encrypted salt should be the same as the low byte of the CRC. If not
it's assumed that the provided password is incorrect. (If it matches
there's still a remote chance that it's incorrect but overall we can save a
lot of wasted effort.) This isn't an issue in streaming mode - just use 0 -
but it requires a way to get that value to the constructor when the header
value is not 0.

Thoughts?

Bear

Reply via email to