private void _EmitOne(System.IO.Stream outstream, out ZipCrypto cipher) { // If PKZip (weak) encryption is in use, then the entry data is preceded by // 12-byte "encryption header" for the entry. byte[] encryptionHeader = null; cipher = null; if (_Password != null && Encryption == EncryptionAlgorithm.PkzipWeak) { cipher = new ZipCrypto(); // apply the password to the keys cipher.InitCipher(_Password); // generate the random 12-byte header: var rnd = new System.Random(); encryptionHeader = new byte[12]; rnd.NextBytes(encryptionHeader); // Here, it is important to encrypt the random header, INCLUDING the final byte // which is the high-order byte of the CRC32. We must do this before // we encrypt the file data. This step changes the state of the cipher, or in the // words of the PKZIP spec, it "further initializes" the cipher keys. // No way around this: must read the stream to compute the actual CRC FigureCrc32(); encryptionHeader[11] = (byte)((this._Crc32 >> 24) & 0xff); byte[] cipherText = cipher.EncryptMessage(encryptionHeader, encryptionHeader.Length); // Write the ciphered bonafide encryption header. outstream.Write(cipherText, 0, cipherText.Length); } // write the (potentially compressed, potentially encrypted) file data _WriteFileData(cipher, outstream); _TotalEntrySize = _LengthOfHeader + _CompressedSize; }