private Stream CreateAndInitDecryptionStream(Stream baseStream, ZipEntry entry) {
CryptoStream result=null;
if ((entry.Version<ZipConstants.VersionStrongEncryption)
||(entry.Flags&(int)GeneralBitFlags.StrongEncryption)==0) {
var 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 (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;
var saltBytes=new byte[saltLen];
int saltIn=baseStream.Read(saltBytes, 0, saltLen);
if (saltIn!=saltLen)
throw new ZipException("AES Salt expected "+saltLen+" got "+saltIn);
//
var pwdVerifyRead=new byte[2];
baseStream.Read(pwdVerifyRead, 0, 2);
int blockSize=entry.AESKeySize/8; // bits to bytes
var 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{
throw new ZipException("Decryption method not supported");
}
}
return result;
}