Exemplo n.º 1
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="stream">The stream on which to perform the cryptographic transformation.</param>
        /// <param name="transform">Instance of ZipAESTransform</param>
        /// <param name="mode">Read or Write</param>
        public ZipAESStream(Stream stream, ZipAESTransform transform, CryptoStreamMode mode)
            : base(stream, transform, mode)
        {
            _stream = stream;
            _transform = transform;
            _slideBuffer = new byte[1024];

            _blockAndAuth = CRYPTO_BLOCK_SIZE + AUTH_CODE_LENGTH;

            // mode:
            //  CryptoStreamMode.Read means we read from "stream" and pass decrypted to our Read() method.
            //  Write bypasses this stream and uses the Transform directly.
            if (mode != CryptoStreamMode.Read)
            {
                throw new Exception("ZipAESStream only for read");
            }
        }
Exemplo n.º 2
0
        private Stream CreateAndInitDecryptionStream(Stream baseStream, ZipEntry entry)
        {
            CryptoStream result = null;

            if ((entry.Version < ZipConstants.VersionStrongEncryption)
                || (entry.Flags & (int)GeneralBitFlags.StrongEncryption) == 0)
            {
                PkzipClassicManaged classicManaged = new PkzipClassicManaged();

                OnKeysRequired(entry.Name);
                if (HaveKeys == false)
                {
                    throw new ZipException("No password available for encrypted stream");
                }

                result = new CryptoStream(baseStream, classicManaged.CreateDecryptor(key, null), CryptoStreamMode.Read);
                CheckClassicPassword(result, entry);
            }
            else
            {
            #if !NET_1_1 && !NETCF_2_0
                if (entry.Version == ZipConstants.VERSION_AES)
                {
                    //
                    OnKeysRequired(entry.Name);
                    if (HaveKeys == false)
                    {
                        throw new ZipException("No password available for AES encrypted stream");
                    }
                    int saltLen = entry.AESSaltLen;
                    byte[] saltBytes = new byte[saltLen];
                    int saltIn = baseStream.Read(saltBytes, 0, saltLen);
                    if (saltIn != saltLen)
                        throw new ZipException("AES Salt expected " + saltLen + " got " + saltIn);
                    //
                    byte[] pwdVerifyRead = new byte[2];
                    baseStream.Read(pwdVerifyRead, 0, 2);
                    int blockSize = entry.AESKeySize / 8;	// bits to bytes

                    ZipAESTransform decryptor = new ZipAESTransform(rawPassword_, saltBytes, blockSize, false);
                    byte[] pwdVerifyCalc = decryptor.PwdVerifier;
                    if (pwdVerifyCalc[0] != pwdVerifyRead[0] || pwdVerifyCalc[1] != pwdVerifyRead[1])
                        throw new Exception("Invalid password for AES");
                    result = new ZipAESStream(baseStream, decryptor, CryptoStreamMode.Read);
                }
                else
            #endif
                {
                    throw new ZipException("Decryption method not supported");
                }
            }

            return result;
        }