/// <summary>
        /// Decrypt file and verify file signature from stream.
        /// </summary>
        /// <param name="inputStream">
        /// The encrypted data input stream.
        /// </param>
        /// <param name="outputStream">
        /// The output stream.
        /// </param>
        /// <param name="privateKeyStream">
        /// The private key stream.
        /// </param>
        /// <param name="publicKeyStream">
        /// The public key stream.
        /// </param>
        /// <param name="passPhrase">
        /// The pass phrase.
        /// </param>
        /// <returns>
        /// The <see cref="bool"/> value indicating whether or not the signature in
        /// the decrypted data is valid.
        /// </returns>
        public static bool DecryptAndVerifyStream(
            Stream inputStream,
            Stream outputStream,
            Stream privateKeyStream,
            Stream publicKeyStream,
            char[] passPhrase)
        {
            PgpPrivateKey             privateKey    = null;
            PgpPublicKeyEncryptedData encryptedData = null;
            var secretKeyRing = new PgpSecretKeyRingBundle(PgpUtilities.GetDecoderStream(privateKeyStream));

            var encryptedDataList = GetEncryptedDataListFromStream(inputStream);

            foreach (PgpPublicKeyEncryptedData dataObject in encryptedDataList.GetEncryptedDataObjects())
            {
                privateKey = PgpKeyHelper.FindSecretKey(secretKeyRing, dataObject.KeyId, passPhrase);
                if (privateKey == null)
                {
                    continue;
                }

                encryptedData = dataObject;
                break;
            }

            if (privateKey == null)
            {
                throw new Exception("Unable to find secret key to decrypt the message");
            }

            var valid = ProcessDecryptionMessageBlocks(encryptedData, outputStream, publicKeyStream, privateKey);

            if (encryptedData.IsIntegrityProtected() && !encryptedData.Verify())
            {
                throw new PgpException("Data is integrity protected but integrity is lost.");
            }

            return(valid);
        }
        /// <summary>
        /// Decrypt a stream using the private key stream.
        /// </summary>
        /// <param name="inputStream">
        /// The stream of the encrypted file.
        /// </param>
        /// <param name="privateKeyStream">
        /// The stream of the private key file.
        /// </param>
        /// <param name="passPhrase">
        /// The pass phrase protecting the secret key.
        /// </param>
        /// <param name="outputFile">
        /// The file path to write the decrypted output to.
        /// </param>
        /// <returns>
        /// The <see cref="bool"/> flag indicating decryption success; false states
        /// decryption failed because of a data integrity check error.
        /// </returns>
        public static bool DecryptFileStream(
            Stream inputStream,
            Stream privateKeyStream,
            string passPhrase,
            string outputFile)
        {
            PgpPrivateKey privateKey = null;
            var           valid      = true;

            try
            {
                PgpEncryptedDataList      encryptedDataList;
                PgpPublicKeyEncryptedData encryptedData = null;

                var objectFactory = new PgpObjectFactory(PgpUtilities.GetDecoderStream(inputStream));
                var secretKeyRing = new PgpSecretKeyRingBundle(PgpUtilities.GetDecoderStream(privateKeyStream));

                var @object = objectFactory.NextPgpObject();
                if (@object is PgpEncryptedDataList)
                {
                    encryptedDataList = (PgpEncryptedDataList)@object;
                }
                else
                {
                    encryptedDataList = (PgpEncryptedDataList)objectFactory.NextPgpObject();
                }

                foreach (PgpPublicKeyEncryptedData pked in encryptedDataList.GetEncryptedDataObjects())
                {
                    privateKey = PgpKeyHelper.FindSecretKey(secretKeyRing, pked.KeyId, passPhrase.ToCharArray());

                    if (privateKey == null)
                    {
                        continue;
                    }

                    encryptedData = pked;
                    break;
                }

                if (privateKey == null)
                {
                    throw new ArgumentException("Secret key for message not found.");
                }

                PgpObjectFactory plainFact;
                using (var clear = encryptedData.GetDataStream(privateKey))
                {
                    plainFact = new PgpObjectFactory(clear);
                }

                var message = plainFact.NextPgpObject();
                if (message is PgpCompressedData)
                {
                    var data = (PgpCompressedData)message;
                    PgpObjectFactory of;

                    using (var compDataIn = data.GetDataStream())
                    {
                        of = new PgpObjectFactory(compDataIn);
                    }

                    message = of.NextPgpObject();
                    if (message is PgpOnePassSignatureList)
                    {
                        message = of.NextPgpObject();
                        var literalData = (PgpLiteralData)message;
                        using (Stream output = File.Create(outputFile))
                        {
                            var unc = literalData.GetInputStream();
                            Streams.PipeAll(unc, output);
                        }
                    }
                    else
                    {
                        var literalData = (PgpLiteralData)message;
                        using (Stream output = File.Create(outputFile))
                        {
                            Stream unc = literalData.GetInputStream();
                            Streams.PipeAll(unc, output);
                        }
                    }
                }
                else if (message is PgpLiteralData)
                {
                    PgpLiteralData literalData = (PgpLiteralData)message;
                    string         unused      = literalData.FileName;

                    using (Stream outputStream = File.Create(outputFile))
                    {
                        Stream unc = literalData.GetInputStream();
                        Streams.PipeAll(unc, outputStream);
                    }
                }
                else if (message is PgpOnePassSignatureList)
                {
                    throw new PgpException("Encrypted message contains a signed message - not literal data.");
                }
                else
                {
                    throw new PgpException("Message is not a simple encrypted file - type unknown.");
                }

                if (encryptedData.IsIntegrityProtected())
                {
                    if (!encryptedData.Verify())
                    {
                        Console.Error.WriteLine("Message failed integrity check");
                        valid = false;
                    }
                    else
                    {
                        Console.Error.WriteLine("Message integrity check passed");
                    }
                }
            }
            catch (PgpException exception)
            {
                PgpCommon.DumpException(exception);
                throw;
            }

            return(valid);
        }