【问题标题】:Bouncy Castle C# PGP Decryption exampleBouncy Castle C# PGP 解密示例
【发布时间】:2012-06-15 12:07:52
【问题描述】:

我昨天找了一整天,似乎找不到在 c# 中使用 Bouncy Castle 进行 PGP 解密的工作示例

【问题讨论】:

标签: c# encryption bouncycastle pgp


【解决方案1】:

终于搞定了。我在其他示例中遇到的主要问题是,我在私钥环中包含了一个用于签名的密钥,该密钥在尝试加载用于解密的密钥时首先出现。这就是为什么我必须在密钥上添加ElGamalPrivateKeyParameters 类型的检查。

下面是我的代码。不是很干净,但很管用。

        private static PgpPrivateKey GetPrivateKey(string privateKeyPath)
    {
        using (Stream keyIn = File.OpenRead(privateKeyPath))
        using (Stream inputStream = PgpUtilities.GetDecoderStream(keyIn))
        {
            PgpSecretKeyRingBundle secretKeyRingBundle = new PgpSecretKeyRingBundle(inputStream);

            PgpSecretKey key = null;
            foreach (PgpSecretKeyRing kRing in secretKeyRingBundle.GetKeyRings())
            {
                foreach (PgpSecretKey secretKey in kRing.GetSecretKeys())
                {
                    PgpPrivateKey privKey = secretKey.ExtractPrivateKey("1234567890".ToCharArray());

                    if (privKey.Key.GetType() ==
                        typeof (Org.BouncyCastle.Crypto.Parameters.ElGamalPrivateKeyParameters))
                        //Org.BouncyCastle.Crypto.Parameters.ElGamalPrivateKeyParameters
                    {
                        return privKey;
                    }
                }

            }
        }
        
        return null;
    }





    public static void Decrypt(Stream input, string outputpath, String privateKeyPath)
    {
        input = PgpUtilities.GetDecoderStream(input);
        try
        {
            PgpObjectFactory pgpObjF = new PgpObjectFactory(input);
            PgpEncryptedDataList enc;
            PgpObject obj = pgpObjF.NextPgpObject();
            if (obj is PgpEncryptedDataList)
            {
                enc = (PgpEncryptedDataList)obj;
            }
            else
            {
                enc = (PgpEncryptedDataList)pgpObjF.NextPgpObject();
            }

       


            
            PgpPrivateKey privKey = GetPrivateKey(privateKeyPath);


            PgpPublicKeyEncryptedData pbe = enc.GetEncryptedDataObjects().Cast<PgpPublicKeyEncryptedData>().First();
            Stream clear;
            clear = pbe.GetDataStream(privKey);
            PgpObjectFactory plainFact = new PgpObjectFactory(clear);
            PgpObject message = plainFact.NextPgpObject();
            if (message is PgpCompressedData)
            {
                PgpCompressedData cData = (PgpCompressedData)message;
                Stream compDataIn = cData.GetDataStream();
                PgpObjectFactory o = new PgpObjectFactory(compDataIn);
                message = o.NextPgpObject();
                if (message is PgpOnePassSignatureList)
                {
                    message = o.NextPgpObject();
                    PgpLiteralData Ld = null;
                    Ld = (PgpLiteralData)message;
                    Stream output = File.Create(outputpath + "\\" + Ld.FileName);
                    Stream unc = Ld.GetInputStream();
                    Streams.PipeAll(unc, output);
                }
                else
                {
                    PgpLiteralData Ld = null;
                    Ld = (PgpLiteralData)message;
                    //Stream output = File.Create(outputpath + "\\" + Ld.FileName);
                    Stream output = File.Create(outputpath);
                    Stream unc = Ld.GetInputStream();
                    Streams.PipeAll(unc, output);
                }
            }
        }
        catch (Exception e)
        {
            throw new Exception(e.Message);
        }
    }

【讨论】:

  • @GeorgePligor:嗨,我是 PGP 的新手,必须以 pgp 格式加密我的 csv 以满足某些要求,我找到了实现该功能的代码,但仍然难以理解密钥库和密钥。你能建议我从哪里得到钥匙吗?公共和私人。
  • 不适合我if (message is PgpCompressedData) 总是假的
  • 我的 'message is PgpCompressedData' 为真,但随后 'message = o.NextPgpObject();'始终为空,有什么想法吗?此外,我没有得到 ElGamalKeyParameters 键类型,而是类型键 - 仅限 RsaPrivateCrtKeyParameters...
  • 我意识到这是不久前的事了,但var akp = new AsymmetricKeyParameter(true); 行给出了错误:无法创建抽象类或接口的实例(此外,为什么它首先存在,你不是甚至在该块中使用变量 akp)。
【解决方案2】:

我遇到了 Ron Harlev 的 Decrypt 函数在程序终止之前保存输出文件的问题。我在 Stream 周围添加了一些 using 语句来解决这个问题。我还替换了硬编码密码以支持输入参数。我希望有人觉得这很有用。

private static bool DecryptFile(Stream inputStream, string outputDir, char[] passPhrase, string privateKeyLoc)
    {
        try
        {
            using (var newStream = PgpUtilities.GetDecoderStream(inputStream))
            {
                PgpObjectFactory pgpObjF = new PgpObjectFactory(newStream);
                PgpEncryptedDataList enc;
                PgpObject obj = pgpObjF.NextPgpObject();
                if (obj is PgpEncryptedDataList)
                {
                    enc = (PgpEncryptedDataList)obj;
                }
                else
                {
                    enc = (PgpEncryptedDataList)pgpObjF.NextPgpObject();
                }

                PgpPrivateKey privKey = GetPrivateKey(privateKeyLoc, passPhrase, logger);

                PgpPublicKeyEncryptedData pbe = enc.GetEncryptedDataObjects().Cast<PgpPublicKeyEncryptedData>().First();

                using (Stream clear = pbe.GetDataStream(privKey))
                {
                    PgpObjectFactory plainFact = new PgpObjectFactory(clear);
                    PgpObject message = plainFact.NextPgpObject();

                    if (message is PgpCompressedData)
                    {
                        PgpCompressedData cData = (PgpCompressedData)message;
                        Stream compDataIn = cData.GetDataStream();
                        PgpObjectFactory o = new PgpObjectFactory(compDataIn);
                        message = o.NextPgpObject();
                        if (message is PgpOnePassSignatureList)
                        {
                            message = o.NextPgpObject();
                        }
                        PgpLiteralData Ld = null;
                        Ld = (PgpLiteralData)message;
                        using (Stream output = File.Create(outputDir + "\\" + Ld.FileName))
                        {
                            Stream unc = Ld.GetInputStream();
                            Streams.PipeAll(unc, output);
                        }
                    }
                }
            }

            return true;
        }
        catch (Exception e)
        {
            throw new Exception(e.Message);
            return false;
        }
    }

【讨论】:

    猜你喜欢
    • 2021-11-04
    • 2012-06-21
    • 2011-01-15
    • 1970-01-01
    • 2020-09-01
    • 1970-01-01
    • 2018-05-20
    • 1970-01-01
    • 2011-08-20
    相关资源
    最近更新 更多