我昨天一直在寻找一整天,我似乎找不到在 c# 中使用 Bouncy Castle 进行 PGP 解密的工作示例
问问题
16357 次
2 回答
9
终于让它工作了。我在其他示例中遇到的主要问题是,我的私钥环包含一个用于签名的密钥,当尝试加载用于解密的密钥时,该密钥首先出现。这就是为什么我必须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);
}
}
于 2012-06-12T21:53:36.873 回答
5
在程序终止之前,我遇到了 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;
}
}
于 2015-03-26T16:26:14.050 回答