c# - 使用 BouncyCaSTLe c# 进行 PgP 加密和解密

标签 c# encryption bouncycastle pgp

我看过很多帖子,遵循了很多教程,但似乎都没有用。有时,他们会引用一些未找到的类。能否向我指出一个位置,在那里我可以获得一个简单的教程,展示如何加密和解密文件。

我是 Pgp 的新手,欢迎任何帮助。

最佳答案

我知道这个问题已经有好几年了,但它在 Google 中仍然是使用 Bouncy CaSTLe 进行 PGP 解密相关搜索的第一名或第二名。由于似乎很难找到一个完整、简洁的示例,所以我想在这里分享我用于解密 PGP 文件的工作解决方案。这只是源文件中包含的 Bouncy CaSTLe 示例的修改版本。

using System;
using System.IO;
using Org.BouncyCastle.Bcpg.OpenPgp;
using Org.BouncyCastle.Utilities.IO;

namespace PGPDecrypt
{
    class Program
    {
        static void Main(string[] args)
        {
            DecryptFile(
                @"path_to_encrypted_file.pgp",
                @"path_to_secret_key.asc",
                "your_password_here".ToCharArray(), 
                "output.txt"
            );
        }

        private static void DecryptFile(
            string inputFileName,
            string keyFileName,
            char[] passwd,
            string defaultFileName)
        {
            using (Stream input = File.OpenRead(inputFileName),
                   keyIn = File.OpenRead(keyFileName))
            {
                DecryptFile(input, keyIn, passwd, defaultFileName);
            }
        }

        private static void DecryptFile(
            Stream inputStream,
            Stream keyIn,
            char[] passwd,
            string defaultFileName)
        {
            inputStream = PgpUtilities.GetDecoderStream(inputStream);

            try
            {
                PgpObjectFactory pgpF = new PgpObjectFactory(inputStream);
                PgpEncryptedDataList enc;

                PgpObject o = pgpF.NextPgpObject();
                //
                // the first object might be a PGP marker packet.
                //
                if (o is PgpEncryptedDataList)
                {
                    enc = (PgpEncryptedDataList)o;
                }
                else
                {
                    enc = (PgpEncryptedDataList)pgpF.NextPgpObject();
                }

                //
                // find the secret key
                //
                PgpPrivateKey sKey = null;
                PgpPublicKeyEncryptedData pbe = null;
                PgpSecretKeyRingBundle pgpSec = new PgpSecretKeyRingBundle(
                    PgpUtilities.GetDecoderStream(keyIn));

                foreach (PgpPublicKeyEncryptedData pked in enc.GetEncryptedDataObjects())
                {
                    sKey = FindSecretKey(pgpSec, pked.KeyId, passwd);

                    if (sKey != null)
                    {
                        pbe = pked;
                        break;
                    }
                }

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

                Stream clear = pbe.GetDataStream(sKey);

                PgpObjectFactory plainFact = new PgpObjectFactory(clear);

                PgpObject message = plainFact.NextPgpObject();

                if (message is PgpCompressedData)
                {
                    PgpCompressedData cData = (PgpCompressedData)message;
                    PgpObjectFactory pgpFact = new PgpObjectFactory(cData.GetDataStream());

                    message = pgpFact.NextPgpObject();
                }

                if (message is PgpLiteralData)
                {
                    PgpLiteralData ld = (PgpLiteralData)message;

                    string outFileName = ld.FileName;
                    if (outFileName.Length == 0)
                    {
                        outFileName = defaultFileName;
                    }

                    Stream fOut = File.Create(outFileName);
                    Stream unc = ld.GetInputStream();
                    Streams.PipeAll(unc, fOut);
                    fOut.Close();
                }
                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 (pbe.IsIntegrityProtected())
                {
                    if (!pbe.Verify())
                    {
                        Console.Error.WriteLine("message failed integrity check");
                    }
                    else
                    {
                        Console.Error.WriteLine("message integrity check passed");
                    }
                }
                else
                {
                    Console.Error.WriteLine("no message integrity check");
                }
            }
            catch (PgpException e)
            {
                Console.Error.WriteLine(e);

                Exception underlyingException = e.InnerException;
                if (underlyingException != null)
                {
                    Console.Error.WriteLine(underlyingException.Message);
                    Console.Error.WriteLine(underlyingException.StackTrace);
                }
            }
        }

        private static PgpPrivateKey FindSecretKey(PgpSecretKeyRingBundle pgpSec, long keyID, char[] pass)
        {
            PgpSecretKey pgpSecKey = pgpSec.GetSecretKey(keyID);

            if (pgpSecKey == null)
            {
                return null;
            }

            return pgpSecKey.ExtractPrivateKey(pass);
        }
    }
}

关于c# - 使用 BouncyCaSTLe c# 进行 PgP 加密和解密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6987699/

相关文章:

ios - 在 iOS 中离线打开和存储加密文档

c# - 想做一个 php get_include_files() 增强

c# - 如何使用 JavaScript 解密 AesCryptoServiceProvider?

c# - 在 C# .NET MVC 应用程序中执行计划任务

c# - 什么相当于 C# 中的 X509EncodedKeySpec

java - 如何从 Java X509 证书获取 BasicConstraints 扩展

java - 充气城堡 PKCS7 填充物

java - 在 bouncycaSTLe 中从私有(private)恢复 PGP 公钥

c# - 在 asp.net mvc 中应该在哪里创建/操作 View 模型?

c# - SkiaSharp 笔划是否有 "inset"对齐?