With version 1.2 pkcrack has become one of those "fire & forget" programs.  If
you are a hacker of the experimental kind you may want to look at the "more
complete instructions" below. Otherwise, stick to the "simple instructions".

The first thing you have to know is that this program applies a *known
plaintext* attack to an encrypted file. A known-plaintext-attack recovers
a password using the encrypted file and (part of) the unencrypted file.

Before you ask why somebody may want to know the password when he already
knows the plaintext think of the following situations:

  a) There's usually a large number of files in a ZIP-archive. All these files
     are encrypted using the same password. So if you know one of the files,
     you can recover the password and decrypt the other files.

  b) You need to know only a part of the plaintext (at least 13 bytes). Many
     files have commonly known headers, like DOS .EXE-files. Knowing a
     reasonably long header you can recover the password and decrypt the
     entire file.

Back to the program.

Simple Instructions
- - -------------------

You need two files: 
  a) the ZIP-archive which you want decrypted, and
  b) another ZIP-archive, containing at least one of the files from the
     encrypted archive in *unencrypted* form. This one has to be compressed
     with the same compression method used for the encrypted file.

Now, enter

  pkcrack -C <encrypted-ZIP> -c <ciphertextname> -P <plaintext-ZIP> 
          -p <plaintextname> -d <decrypted_file>

(This is supposed to be a single line. I've wrapped it because it doesn't fit
 in 80 chars. "Real computer scientists never comment their code - the
 identifiers are so long they can't afford the disc space." :-/ )

<encrypted-ZIP>  is the name (and path) of the encrypted ZIP-archive 
		 (see a) above)
<ciphertextname> is the name of the file *in the archive*, for which you have
		 the plaintext
<plaintext-ZIP>  is the name (and path) of the ZIP-archive containing the
		 compressed plaintext (see b) above)
<plaintextname>  is the name of the file *in the archive* containing the known
		 plaintext
<decrypted_file> is the name of a file to which the decrypted archive will be
		 written

All you have to do now is wait a little. Depending on the size of the 
plaintext and the speed of your computer after about an hour the program
should terminate. If the plaintext is very short (less than 100 byte or so),
it will probably take a lot longer.

After pkcrack is finished, you will find the decrypted archive in the file
<decrypted_file>. You can unzip it using any unzip-program, e. g. pkunzip
under DOS, or unzip under UNIX.

If <decrypted_file> doesn't exist, or if unzipping it produces CRC-errors,
there are several things that may have gone wrong:

 * Maybe you used the wrong plaintext. Find better plaintext.
 * Maybe you used the correct plaintext but used the wrong compression method.
   Compress the plaintext with a different method.
 * Maybe pkcrack found more than one set of matching 'keys' and used the wrong
   one to decrypt the file. Examine the output of pkcrack, and use the
   sets of key[012]-values with the "zipdecrypt" program to decrypt the file.
 * Maybe something else went wrong. Now you're in trouble. Read the "more
   complete instructions" and try to understand why the program failed. Read
   the FAQ below.

More Complete Instructions
- - --------------------------

This section will explain some of the more esoteric options of pkcrack, as
well as some of the other programs in this package.

Just like in the "simple instructions" you need two files. Not necessarily
ZIP-archives, though. You can specify any file containing nothing but plain
data, i. e. no ZIP-headers, and no other fancy stuff. In that case, simply
*don't* specify the -C or -P options, but only the -c and -p options.

So there are two possible ways to tell pkcrack where to find the ciphertext:

 * -C <encrypted-ZIP> -c <ciphertextname> (see above), or
 * -c <ciphertextname>

As I said, in the latter case <ciphertextname> is the name of a file 
containing *nothing but* encrypted data.

Analogously there are two possible ways to specify the plaintext:

 * -P <plaintext-ZIP> -p <plaintextname> (see above), or
 * -p <plaintextname>

In the latter case, <plaintextname> is the name of a file containing *nothing 
but* (compressed) plaintext.

Note that PkZip prepends 12 random bytes to the compressed data before
encryption, so the ciphertextfile has to be 12 bytes longer than the plaintext.
If you know only part of the plaintext, the plaintext can be even shorter.
Usually, though, a difference of more or less than 12 bytes in the file sizes
indicates wrong plaintext, or wrong compression method of the plaintext.

If you want to extract data from a ZIP-archive, you can use the "extract"
program contained in this package. Invoke it by entering

  extract <ZIP-name> <name-in-ZIP>

This will extract the (possibly encrypted and/or compressed) data stored in
the archive <ZIP-name> under the name <name-in-ZIP>, and write those data to
the file <name-in-ZIP> in the current directory.

Another option used in the "simple instructions" above is the 
- - -d <decrypted_file> - option. It tells pkcrack to decrypt the archive
specified with the -C option and write the decrypted results to the file
<decrypted_file>. Naturally, it can only be used in conjunction with the
- - -C option. 

If you do not specify the -d option, pkcrack will try to find a PkZip-password
when it has found a set of keys. If it finds a password, you can use it to
decrypt the archive with the pkunzip-program. If it doesn't, you can use the
set of keys found by pkcrack with the zipdecrypt program contained in this
package to decrypt the archive. Zipdecrypt must be called as follows:

  zipdecrypt <key0> <key1> <key2> <encrypted_archive> <decrypted_archive>

where <key0>, <key1>, <key2> is a set of keys found by pkcrack,
<encrypted_archive> is the name of the archive to be decrypted, and
<decrypted_archive> is the name of the file to which the archive will be
written by zipdecrypt.

One option to pkcrack has not been mentioned yet: with -o <offset> you can
specify an offset of the plaintext data into the ciphertext. This is for
the special case that the known plaintext starts somewhere in the middle
of the encrypted data. The default value for <offset> is 0, i. e. the 12
encrypted random bytes are *not* to be included in the offset.

There is another possible application of the <offset>: the so-called "random"
bytes aren't that random. Older versions of PkZip used the CRC-checksum of
the file as the last 4 "random" bytes, newer versions use "only" one byte
of CRC. In that case you have to prepend the known CRC-bytes before the
known plaintext file, and specify a *negative* offset (e. g. -1 if you
know the last of the "random" bytes). This feature has not been tested
very thoroughly. Be warned.

The one thing that remains to be explained is the findkey program. You can
use it to find a PkZip-password for a set of key[012]-values found by
pkcrack. This is exactly what pkcrack does if you do *not* specify the -d
option. Periodically, findkey prints information about its progress which
can be used to restart the program at a later time. The information printed
is of the form

  10: xx, or
  11: xxxx, or
  12: xxxxxx and so on.

To restart findkey, enter

  findkey <key0> <key1> <key2> <pwdlen> <initvalue>

where <key0>, <key1>, <key2> is a set of keys found by pkcrack, <pwdlen> is
10 or 11 or 12 (depending on the point where you want to resume), and
<initvalue> is the "xx" printed by findkey. <pwdlen> and <initvalue> are
optional parameters.

Note that findkey will take *very* long to find long passwords. There are
255 times as many possible passwords with a <pwdlen> of 11 as with a <pwdlen>
of 10. It is probably wiser to use the zipdecrypt program instead.