示例#1
0
文件: ZipEntry.cs 项目: hiling/WebZip
        private ZipCrypto SetupCipher(string password)
        {
            ZipCrypto cipher = null;
            // decrypt the file header data here if necessary.
            if (Encryption == EncryptionAlgorithm.PkzipWeak)
            {
                if (password == null)
                    throw new BadPasswordException("This entry requires a password.");

                cipher = new ZipCrypto();
                cipher.InitCipher(password);

                // Decrypt the header.  This has a side effect of "further initializing the
                // encryption keys" in the traditional zip encryption.
                byte[] DecryptedHeader = cipher.DecryptMessage(_WeakEncryptionHeader, _WeakEncryptionHeader.Length);

                // CRC check
                // According to the pkzip spec, the final byte in the decrypted header
                // is the highest-order byte in the CRC. We check it here.
                if (DecryptedHeader[11] != (byte)((_Crc32 >> 24) & 0xff))
                {
                    // In the case that bit 3 of the general purpose bit flag is set to indicate
                    // the presence of an 'Extended File Header', the last byte of the decrypted
                    // header is sometimes compared with the high-order byte of the lastmodified
                    // time, and not the CRC, to verify the password.
                    //
                    // This is not documented in the PKWare Appnote.txt.
                    // This was discovered this by analysis of the Crypt.c source file in the InfoZip library
                    // http://www.info-zip.org/pub/infozip/

                    if ((_BitField & 0x0008) != 0x0008)
                    {
                        throw new BadPasswordException("The password did not match.");
                    }
                    else if (DecryptedHeader[11] != (byte)((_TimeBlob >> 8) & 0xff))
                    {
                        throw new BadPasswordException("The password did not match.");
                    }
                }

                // We have a good password.
            }

            return cipher;
        }