/// <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);
        }
        /// <summary>
        /// Encrypt a file as specified by the input file path.
        /// </summary>
        /// <param name="inputFile">
        /// The file to encrypt.
        /// </param>
        /// <param name="outputFile">
        /// The file to write the encrypted content to.
        /// </param>
        /// <param name="publicKeyFile">
        /// The path to the public key file to use for encryption.
        /// </param>
        /// <param name="symmetricKeyAlgorithm">
        /// Encryption algorithm.
        /// </param>
        /// <param name="armor">
        /// Should the encrypted file be written using ASCII armor?
        /// </param>
        /// <param name="withIntegrityCheck">
        /// Should the integrity be verified?
        /// </param>
        /// <param name="compressionAlgorithm">
        /// Compression algorithm to use.
        /// </param>
        public static void EncryptFile(
            string inputFile,
            string outputFile,
            string publicKeyFile,
            SymmetricKeyAlgorithmTag symmetricKeyAlgorithm = SymmetricKeyAlgorithmTag.Aes256,
            bool armor = true,
            bool withIntegrityCheck = true,
            CompressionAlgorithmTag compressionAlgorithm = CompressionAlgorithmTag.Zip)
        {
            try
            {
                using (Stream publicKeyStream = File.OpenRead(publicKeyFile))
                {
                    PgpPublicKey encKey = PgpKeyHelper.ReadPublicKey(publicKeyStream);

                    using (var memoryStream = new MemoryStream())
                    {
                        var compressedDataGenerator = new PgpCompressedDataGenerator(compressionAlgorithm);
                        WriteFileToLiteralData(
                            compressedDataGenerator.Open(memoryStream),
                            PgpLiteralData.Binary,
                            new FileInfo(inputFile));

                        compressedDataGenerator.Close();
                        var encryptedDataGenerator = new PgpEncryptedDataGenerator(
                            symmetricKeyAlgorithm,
                            withIntegrityCheck,
                            new SecureRandom());

                        encryptedDataGenerator.AddMethod(encKey);
                        var bytes = memoryStream.ToArray();

                        using (Stream outputStream = File.Create(outputFile))
                        {
                            if (armor)
                            {
                                using (var armoredStream = new ArmoredOutputStream(outputStream))
                                    using (var encryptedStream = encryptedDataGenerator.Open(armoredStream, bytes.Length))
                                    {
                                        encryptedStream.Write(bytes, 0, bytes.Length);
                                    }
                            }
                            else
                            {
                                using (
                                    Stream encryptedOutputStream = encryptedDataGenerator.Open(
                                        outputStream,
                                        bytes.Length))
                                {
                                    encryptedOutputStream.Write(bytes, 0, bytes.Length);
                                }
                            }
                        }
                    }
                }
            }
            catch (PgpException exception)
            {
                PgpCommon.DumpException(exception);
                throw;
            }
        }