How to use WinZip AES encryption

TrueZIP 7.3 or later support the WinZip AES encryption and authentication scheme. This post shows you if and how to use it.

Disclaimer

Before I show you how to use the WinZip AES scheme with TrueZIP 7.3+, I need to tell you that the security level of the WinZip AES scheme is contended: In 2004, Tadayoshi Kohno wrote an excellent paper named “Attacking and Repairing the WinZip Encryption Scheme” which provides you with all the details if you want. I’m not going into these details here, but it should suffice to say that the most important weakness is that the WinZip AES scheme encrypts and authenticates entry contents only while all meta data is left unencrypted and unauthenticated!

This opens the door to many attacks: For example, an attacker could read the central directory or replace any entry without notice. Unfortunately, this was never fixed by WinZip Inc. In all fairness, I need to say it would be hard to fix this without breaking binary compatibility - they might as well invent something new.

Use Case

So why bother with this scheme at all? Well, WinZip AES is popular, so you might not have a choice and need to read or update this file format. Or you might need to append encrypted and authenticated entries to an existing ZIP file, which is not possible with the alternative RAES scheme in the module TrueZIP Driver ZIP.RAES (TZP). Of course, appending would only make sense if the existing ZIP file solely contains WinZip AES entries, i.e. ZIP entries which have their content encrypted and authenticated according to the WinZip AES scheme.

In any other case, I’ld recommend to use the RAES scheme in the module TrueZIP Driver ZIP.RAES (TZP). The RAES scheme is a wrapper file format which encrypts and authenticates it’s entire pay load using AES-256 with HMac/SHA-256 according to PKCS #12 as its PBKDF (if this doesn’t make much sense to you, never mind - just try it).

Using the File* API

First, for comparison, let’s recap how to write an encrypted and authenticated entry to a ZIP.RAES file by copying the file named file to the entry named entry within the ZIP.RAES file named archive.tzp with the API of the client module TrueZIP File*:

TFile src = new TFile("file");
TFile dst = new TFile("archive.tzp/entry"); // detect ZIP.RAES file name with .tzp extension
src.cp(dst); // copy entry to JAR file with RAES encryption and authentication

As you can see, it’s dead simple: By declaring the object dst to refer to the path archive.tzp/entry, TrueZIP detects that you want this entry to be located in a ZIP.RAES file. The following call to the copy method cp() then writes the new entry to the archive file. Mind that this example presumes that the JARs of the driver modules TrueZIP Driver FILE and TrueZIP Driver ZIP.RAES (TZP) are present on the runtime class path.

With the WinZip AES scheme however, you are writing to a regular ZIP file and hence you need to tell the API that you want entries to get encrypted and authenticated when writing them:

TFile src = new TFile("file");
TFile dst = new TFile("archive.zip/entry"); // detect ZIP file name with .zip extension
TConfig config = TConfig.get();
config.setOutputPreferences(config.getOutputPreferences().set(FsOutputOption.ENCRYPT));
src.cp(dst); // copy entry to ZIP file with WinZip AES encryption and authentication

Similar to the previous example, by declaring the object dst to refer to the path "archive.zip/entry", TrueZIP detects that you want this entry to be located in a ZIP file. In order to tell the ZIP driver to encrypt and authenticate the entry according to the WinZip AES scheme however, you have to obtain the TConfig object which represents the current configuration by calling TConfig.get() and change it so that the FsOutputOption.ENCRYPT is set before you actually write the ZIP entry by using the cp() method again. Mind that this example presumes that the JARs of the driver modules TrueZIP Driver FILE and TrueZIP Driver ZIP are present on the runtime class path.

Note that the TConfig object obtained by calling TConfig.get() always refers to the current configuration. By default, this TConfig object is also identical to the global configuration, which is shared by all threads. In most cases however, you don’t want your changes to affect any other threads. As an alternative, you can make the current configuration inheritable thread local like this:

TFile src = new TFile("file");
TFile dst = new TFile("archive.zip/entry"); // detect ZIP file name with .zip extension
TConfig config = TConfig.push();
try {
    config.setOutputPreferences(config.getOutputPreferences().set(FsOutputOption.ENCRYPT));
    src.cp(dst); // copy entry to ZIP file with WinZip AES encryption and authentication
} finally {
    config.close();
}

The call to TConfig.push() copies the current configuration and pushes it as a new element on the inheritable thread local stack of configurations. Accordingly, once done, the call to TConfig.close() pops this copy off the stack again.

Using the try-with-resources statement in Java 7, you could even shorten this to:

TFile src = new TFile("file");
TFile dst = new TFile("archive.zip/entry"); // detect ZIP file name with .zip extension
try (TConfig config = TConfig.push()) {
    config.setOutputPreferences(config.getOutputPreferences().set(FsOutputOption.ENCRYPT));
    src.cp(dst); // copy entry to ZIP file with WinZip AES encryption and authentication
}

Key Management

When you run these examples, you should see a Swing dialog prompting you for a password for the archive files archive.tzp or archive.zip respectively. This is how it looks in English:

And this is how it looks in German:

If the JVM is running headless, you will see a console prompt instead. If the console is not available too, you should get an exception.

Typically, you will want to implement your own password/key management. For the WinZip AES scheme, you can do so by following the instructions in this article: https://christian-schlichtherle.bitbucket.io/truezip/truezip-driver/truezip-driver-zip/key-management.html. For the RAES scheme, you can do so by following the instructions in this article: https://christian-schlichtherle.bitbucket.io/truezip/truezip-driver/truezip-driver-tzp/key-management.html.

That’s it - enjoy TrueZIP!