private Stream CreateAndInitDecryptionStream(Stream baseStream, ZipEntry entry) { if ((entry.Version < 50) || ((entry.Flags & 0x40) == 0)) { PkzipClassicManaged managed = new PkzipClassicManaged(); OnKeysRequired(entry.Name); if (!HaveKeys) { throw new ZipException("No password available for encrypted stream"); } CryptoStream classicCryptoStream = new CryptoStream(baseStream, managed.CreateDecryptor(key, null), CryptoStreamMode.Read); CheckClassicPassword(classicCryptoStream, entry); return classicCryptoStream; } if (entry.Version != 0x33) { throw new ZipException("Decryption method not supported"); } OnKeysRequired(entry.Name); if (!HaveKeys) { throw new ZipException("No password available for AES encrypted stream"); } int aESSaltLen = entry.AESSaltLen; byte[] buffer = new byte[aESSaltLen]; int num2 = baseStream.Read(buffer, 0, aESSaltLen); if (num2 != aESSaltLen) { throw new ZipException(string.Concat(new object[] { "AES Salt expected ", aESSaltLen, " got ", num2 })); } byte[] buffer2 = new byte[2]; baseStream.Read(buffer2, 0, 2); int blockSize = entry.AESKeySize / 8; ZipAESTransform transform = new ZipAESTransform(rawPassword_, buffer, blockSize, false); byte[] pwdVerifier = transform.PwdVerifier; if ((pwdVerifier[0] != buffer2[0]) || (pwdVerifier[1] != buffer2[1])) { throw new Exception("Invalid password for AES"); } return new ZipAESStream(baseStream, transform, CryptoStreamMode.Read); }
private int InitialRead(byte[] destination, int offset, int count) { if (!CanDecompressEntry) { throw new ZipException("Library cannot extract this entry. Version required is (" + entry.Version.ToString() + ")"); } if (entry.IsCrypted) { if (password == null) { throw new ZipException("No password set."); } PkzipClassicManaged managed = new PkzipClassicManaged(); byte[] rgbKey = PkzipClassic.GenerateKeys(ZipConstants.ConvertToArray(password)); base.inputBuffer.CryptoTransform = managed.CreateDecryptor(rgbKey, null); byte[] outBuffer = new byte[12]; base.inputBuffer.ReadClearTextBuffer(outBuffer, 0, 12); if (outBuffer[11] != entry.CryptoCheckValue) { throw new ZipException("Invalid password"); } if (base.csize < 12L) { if ((entry.Flags & 8) == 0) { throw new ZipException(string.Format("Entry compressed size {0} too small for encryption", base.csize)); } } else { base.csize -= 12L; } } else { base.inputBuffer.CryptoTransform = null; } if ((base.csize > 0L) || ((flags & 8) != 0)) { if ((method == 8) && (base.inputBuffer.Available > 0)) { base.inputBuffer.SetInflaterInput(base.inf); } internalReader = BodyRead; return BodyRead(destination, offset, count); } internalReader = ReadingNotAvailable; return 0; }