Crisis.Ionic.Zip.ZipEntry.WriteSecurityMetadata C# (CSharp) Метод

WriteSecurityMetadata() приватный Метод

private WriteSecurityMetadata ( Stream outstream ) : void
outstream Stream
Результат void
        internal void WriteSecurityMetadata(Stream outstream)
        {
            if (Encryption == EncryptionAlgorithm.None)
                return;

            string pwd = this._Password;

            // special handling for source == ZipFile.
            // Want to support the case where we re-stream an encrypted entry. This will involve,
            // at runtime, reading, decrypting, and decompressing from the original zip file, then
            // compressing, encrypting, and writing to the output zip file.

            // If that's what we're doing, and the password hasn't been set on the entry,
            // we use the container (ZipFile/ZipOutputStream) password to decrypt.
            // This test here says to use the container password to re-encrypt, as well,
            // with that password, if the entry password is null.

            if (this._Source == ZipEntrySource.ZipFile && pwd == null)
                pwd = this._container.Password;

            if (pwd == null)
            {
                _zipCrypto_forWrite = null;
#if AESCRYPTO
                _aesCrypto_forWrite = null;
#endif
                return;
            }

            TraceWriteLine("WriteSecurityMetadata: e({0}) crypto({1}) pw({2})",
                           FileName, Encryption.ToString(), pwd);

            if (Encryption == EncryptionAlgorithm.PkzipWeak)
            {
                // If PKZip (weak) encryption is in use, then the encrypted entry data
                // is preceded by 12-byte "encryption header" for the entry.

                _zipCrypto_forWrite = ZipCrypto.ForWrite(pwd);

                // generate the random 12-byte header:
                var rnd = new System.Random();
                byte[] encryptionHeader = new byte[12];
                rnd.NextBytes(encryptionHeader);

                // workitem 8271
                if ((this._BitField & 0x0008) == 0x0008)
                {
                    // In the case that bit 3 of the general purpose bit flag is set to
                    // indicate the presence of a 'data descriptor' (signature
                    // 0x08074b50), the last byte of the decrypted header is sometimes
                    // compared with the high-order byte of the lastmodified time,
                    // rather than the high-order byte of 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/

                    // Also, winzip insists on this!
                    _TimeBlob = Crisis.Ionic.Zip.SharedUtilities.DateTimeToPacked(LastModified);
                    encryptionHeader[11] = (byte)((this._TimeBlob >> 8) & 0xff);
                }
                else
                {
                    // When bit 3 is not set, the CRC value is required before
                    // encryption of the file data begins. In this case there is no way
                    // around it: must read the stream in its entirety to compute the
                    // actual CRC before proceeding.
                    FigureCrc32();
                    encryptionHeader[11] = (byte)((this._Crc32 >> 24) & 0xff);
                }

                // Encrypt the random header, INCLUDING the final byte which is either
                // the high-order byte of the CRC32, or the high-order byte of the
                // _TimeBlob.  Must do this BEFORE encrypting 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.

                byte[] cipherText = _zipCrypto_forWrite.EncryptMessage(encryptionHeader, encryptionHeader.Length);

                // Write the ciphered bonafide encryption header.
                outstream.Write(cipherText, 0, cipherText.Length);
                _LengthOfHeader += cipherText.Length;  // 12 bytes
            }

#if AESCRYPTO
            else if (Encryption == EncryptionAlgorithm.WinZipAes128 ||
                Encryption == EncryptionAlgorithm.WinZipAes256)
            {
                // If WinZip AES encryption is in use, then the encrypted entry data is
                // preceded by a variable-sized Salt and a 2-byte "password
                // verification" value for the entry.

                int keystrength = GetKeyStrengthInBits(Encryption);
                _aesCrypto_forWrite = WinZipAesCrypto.Generate(pwd, keystrength);
                outstream.Write(_aesCrypto_forWrite.Salt, 0, _aesCrypto_forWrite._Salt.Length);
                outstream.Write(_aesCrypto_forWrite.GeneratedPV, 0, _aesCrypto_forWrite.GeneratedPV.Length);
                _LengthOfHeader += _aesCrypto_forWrite._Salt.Length + _aesCrypto_forWrite.GeneratedPV.Length;

                TraceWriteLine("WriteSecurityMetadata: AES e({0}) keybits({1}) _LOH({2})",
                               FileName, keystrength, _LengthOfHeader);

            }
#endif

        }
ZipEntry