Bouncy Castle C#PGP解密示例

昨天我一直在寻找,我似乎无法在c#中找到使用Bouncy Castle的PGP解密的工作示例

终于搞定了。 我与其他样本的主要问题是,我的私钥密钥环包含了一个用于签名的密钥,该密钥在尝试加载密钥进行解密时首先出现。 这就是为什么我必须在密钥上添加对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(); } var akp = new AsymmetricKeyParameter(true); PgpPrivateKey privKey = GetPrivateKey(privateKeyPath); PgpPublicKeyEncryptedData pbe = enc.GetEncryptedDataObjects().Cast().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); } } 

我遇到了Ron Harlev的Decrypt函数保存输出文件的问题,直到程序终止。 我在Stream周围添加了一些使用语句来克服这个问题。 我还替换了硬编码密码,转而使用输入参数。 我希望有人觉得这很有用。

 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(); } var akp = new AsymmetricKeyParameter(true); PgpPrivateKey privKey = GetPrivateKey(privateKeyLoc, passPhrase, logger); PgpPublicKeyEncryptedData pbe = enc.GetEncryptedDataObjects().Cast().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; } }