internal byte[] DecryptInternal(string password, byte[] encryptionInfo, byte[] encryptedPackage) { #region Parse the encryption info data using (System.IO.MemoryStream ms = new System.IO.MemoryStream(encryptionInfo)) { System.IO.BinaryReader reader = new System.IO.BinaryReader(ms); versionMajor = reader.ReadUInt16(); versionMinor = reader.ReadUInt16(); encryptionFlags = (EncryptionFlags)reader.ReadUInt32(); if (encryptionFlags == EncryptionFlags.fExternal) throw new Exception("An external cryptographic provider is not supported"); // Encryption header uint headerLength = reader.ReadUInt32(); int skipFlags = reader.ReadInt32(); headerLength -= 4; sizeExtra = reader.ReadUInt32(); headerLength -= 4; algId = (AlgId)reader.ReadUInt32(); headerLength -= 4; algHashId = (AlgHashId)reader.ReadUInt32(); headerLength -= 4; keySize = reader.ReadInt32(); headerLength -= 4; providerType = (ProviderType)reader.ReadUInt32(); headerLength -= 4; reader.ReadUInt32(); headerLength -= 4; // Reserved 1 reader.ReadUInt32(); headerLength -= 4; // Reserved 2 CSPName = System.Text.UnicodeEncoding.Unicode.GetString(reader.ReadBytes((int)headerLength)); // Encryption verifier saltSize = reader.ReadInt32(); salt = reader.ReadBytes(saltSize); encryptedVerifier = reader.ReadBytes(0x10); verifierHashSize = reader.ReadInt32(); encryptedVerifierHash = reader.ReadBytes(providerType == ProviderType.RC4 ? 0x14 : 0x20); } #endregion #region Encryption key generation Console.WriteLine("Encryption key generation"); byte[] encryptionKey = GeneratePasswordHashUsingSHA1(password); if (encryptionKey == null) return null; #endregion #region Password verification Console.WriteLine("Password verification"); if (PasswordVerifier(encryptionKey)) { Console.WriteLine("Password verification succeeded"); } else { Console.WriteLine("Password verification failed"); throw new InvalidPasswordException("The password is not valid"); } #endregion #region Decrypt // First 8 bytes hold the size of the stream long length = BitConverter.ToInt64(encryptedPackage, 0); // Decrypt the stream using the generated and validated key Console.WriteLine("Decrypt the stream using the generated and validated key"); encryptedPackage = AESDecrypt(encryptedPackage, 8, encryptedPackage.Length-8, encryptionKey); // !! IMPORTANT !! Make sure the final array is the correct size // Failure to do this will cause an error when the decrypted stream // is opened by the System.IO.Packaging.Package.Open() method. byte[] result = encryptedPackage; if (encryptedPackage.Length > length) { result = new byte[length]; Array.Copy(encryptedPackage, result, result.Length); } //using (System.IO.FileStream fs = new System.IO.FileStream(@"c:\x.zip", System.IO.FileMode.Create)) //{ // fs.Write(result, 0, result.Length); //} return result; #endregion }
internal byte[] DecryptInternal(string password, byte[] encryptionInfo, byte[] encryptedPackage) { #region Parse the encryption info data using (System.IO.MemoryStream ms = new System.IO.MemoryStream(encryptionInfo)) { System.IO.BinaryReader reader = new System.IO.BinaryReader(ms); versionMajor = reader.ReadUInt16(); versionMinor = reader.ReadUInt16(); encryptionFlags = (EncryptionFlags)reader.ReadUInt32(); if (encryptionFlags == EncryptionFlags.fExternal) { throw new Exception("An external cryptographic provider is not supported"); } // Encryption header uint headerLength = reader.ReadUInt32(); int skipFlags = reader.ReadInt32(); headerLength -= 4; sizeExtra = reader.ReadUInt32(); headerLength -= 4; algId = (AlgId)reader.ReadUInt32(); headerLength -= 4; algHashId = (AlgHashId)reader.ReadUInt32(); headerLength -= 4; keySize = reader.ReadInt32(); headerLength -= 4; providerType = (ProviderType)reader.ReadUInt32(); headerLength -= 4; reader.ReadUInt32(); headerLength -= 4; // Reserved 1 reader.ReadUInt32(); headerLength -= 4; // Reserved 2 CSPName = System.Text.UnicodeEncoding.Unicode.GetString(reader.ReadBytes((int)headerLength)); // Encryption verifier saltSize = reader.ReadInt32(); salt = reader.ReadBytes(saltSize); encryptedVerifier = reader.ReadBytes(0x10); verifierHashSize = reader.ReadInt32(); encryptedVerifierHash = reader.ReadBytes(providerType == ProviderType.RC4 ? 0x14 : 0x20); } #endregion #region Encryption key generation Console.WriteLine("Encryption key generation"); byte[] encryptionKey = GeneratePasswordHashUsingSHA1(password); if (encryptionKey == null) { return(null); } #endregion #region Password verification Console.WriteLine("Password verification"); if (PasswordVerifier(encryptionKey)) { Console.WriteLine("Password verification succeeded"); } else { Console.WriteLine("Password verification failed"); throw new InvalidPasswordException("The password is not valid"); } #endregion #region Decrypt // First 8 bytes hold the size of the stream long length = BitConverter.ToInt64(encryptedPackage, 0); // Decrypt the stream using the generated and validated key Console.WriteLine("Decrypt the stream using the generated and validated key"); encryptedPackage = AESDecrypt(encryptedPackage, 8, encryptedPackage.Length - 8, encryptionKey); // !! IMPORTANT !! Make sure the final array is the correct size // Failure to do this will cause an error when the decrypted stream // is opened by the System.IO.Packaging.Package.Open() method. byte[] result = encryptedPackage; if (encryptedPackage.Length > length) { result = new byte[length]; Array.Copy(encryptedPackage, result, result.Length); } //using (System.IO.FileStream fs = new System.IO.FileStream(@"c:\x.zip", System.IO.FileMode.Create)) //{ // fs.Write(result, 0, result.Length); //} return(result); #endregion }