我正在寻找一个代码示例,它将向我展示如何使用bouncy castle使用公钥解密pgp文件。我有一些代码可以解密用我提供给用户的密钥加密的文件,但是因为我只有来自客户端的公钥而且我的代码不同。
所以对此有任何帮助将不胜感激。 :)
JD
答案 0 :(得分:2)
您无法使用公钥进行解密,至少在没有对加密方案的复杂攻击的情况下也是如此,因为它们可能允许任何人解密加密的消息。非对称(公钥/私钥)加密背后的想法是使用公钥来防止解密,公钥可以任意共享(它可以是公共的),而只有私钥的持有者才能解密。
主要用于某些非对称算法(如RSA),公钥和私钥对可以互换,但是必须使用私有密钥加密,以便公众key可以用于解密,它只是切换了键的定义。这种行为被用于数字签名,其中消息(通常仅是消息的哈希值)由私钥加密。如果可以使用 public 密钥解密消息/哈希值,则必须使用私钥加密 - 除了密钥所有者之外的任何人都可以使用它。
答案 1 :(得分:0)
我做了一个简单的项目来使用bouncycastle解密pgp消息。
public void Decrypt(Stream encrypted_stream, string output_path)
{
encrypted_stream = PgpUtilities.GetDecoderStream(encrypted_stream);
PgpEncryptedDataList encrypted_data_list;
PgpObjectFactory pgp_factory = new PgpObjectFactory(encrypted_stream);
PgpObject pgp_object = pgp_factory.NextPgpObject();
if (pgp_object is PgpEncryptedDataList)
{
encrypted_data_list = (PgpEncryptedDataList)pgp_object;
}
else
{
encrypted_data_list = (PgpEncryptedDataList)pgp_factory.NextPgpObject();
}
PgpPrivateKey private_key = m_PGPKeys.m_PGPPrivateKey;
PgpPublicKeyEncryptedData public_encrypted_data = null;
IEnumerable encryptedDataObjects = encrypted_data_list.GetEncryptedDataObjects();
foreach (PgpPublicKeyEncryptedData pked in encrypted_data_list.GetEncryptedDataObjects())
{
if (private_key != null)
{
public_encrypted_data = pked;
break;
}
}
Stream clear_stream = public_encrypted_data.GetDataStream(private_key);
PgpObjectFactory plain_factory = new PgpObjectFactory(clear_stream);
PgpObject message = plain_factory.NextPgpObject();
if (message is PgpCompressedData)
{
PgpObjectFactory compressed_data_factory_object = HandleCompressedPGPData(ref message);
if (message is PgpOnePassSignatureList)
{
message = HandleOnePassSingnatureList(output_path, message, compressed_data_factory_object);
}
}
PgpLiteralData literal_data = (PgpLiteralData)message;
Stream output_stream = File.Create(@"C:\PGP\Result7");
Stream unencrypted_stream = literal_data.GetInputStream();
Streams.PipeAll(unencrypted_stream, output_stream);
}
private static PgpObject HandleOnePassSingnatureList(string output_path, PgpObject message, PgpObjectFactory compressed_data_factory_object)
{
message = compressed_data_factory_object.NextPgpObject();
// Literal Data packet contains the body of a message; data that is
//not to be further interpreted.
PgpLiteralData signature_literal_data = null;
signature_literal_data = (PgpLiteralData)message;
Stream signature_output_stream = File.Create(output_path + "\\" + signature_literal_data.FileName);
Stream unencrypted_signature_stream = signature_literal_data.GetInputStream();
Streams.PipeAll(unencrypted_signature_stream, signature_output_stream);
return message;
}
private static PgpObjectFactory HandleCompressedPGPData(ref PgpObject message)
{
PgpCompressedData compressed_data = (PgpCompressedData)message;
Stream compressed_data_in = compressed_data.GetDataStream();
PgpObjectFactory compressed_data_factory_object = new PgpObjectFactory(compressed_data_in);
message = compressed_data_factory_object.NextPgpObject();
return compressed_data_factory_object;
}
您需要创建PgpKeys
类来处理来自密钥环的Pgp公钥和私钥。像这样
class PGPKeys
{
private long m_KeyId;
private string m_PrivateKeyPath;
private string m_PublicKeypath;
private string m_Password;
public PgpPublicKey m_PGPPublicKey { get; private set; }
public PgpPrivateKey m_PGPPrivateKey { get; private set; }
public PgpSecretKey m_PGPSecretKey { get; private set; }
public PGPKeys(string public_key_path, string private_key_path, string password, long key_id)
{
if (!File.Exists(public_key_path))
throw new ArgumentNullException("Could not find the public key at" + public_key_path);
if (!File.Exists(private_key_path))
throw new ArgumentNullException("Could not find the public key at" + private_key_path);
if (String.IsNullOrEmpty(password))
throw new ArgumentNullException("The password must not be null");
if (key_id == 0)
throw new ArgumentNullException("The password must not be null");
m_KeyId = key_id;
m_PGPPublicKey = GetPublicKey(public_key_path);
m_PGPPrivateKey = GetPrivateKey(password, private_key_path);
}
private PgpPrivateKey GetPrivateKey(string password, string private_key_path)
{
PgpSecretKey secret_key = GetSecretKey(private_key_path);
PgpPrivateKey private_key = secret_key.ExtractPrivateKey(password.ToCharArray());
if (private_key == null)
return null;
return private_key;
}
private PgpSecretKey GetSecretKey(string private_key_path)
{
PgpSecretKey secret_key = null;
using (Stream keyin = File.OpenRead(private_key_path))
{
using (Stream private_key_Stream = PgpUtilities.GetDecoderStream(keyin))
{
PgpSecretKeyRingBundle secret_key_ring_bundle = new PgpSecretKeyRingBundle(private_key_Stream);
secret_key = GetLastSecretKey(secret_key_ring_bundle);
}
}
return secret_key;
}
private PgpPublicKey GetPublicKey(string public_key_path)
{
PgpPublicKey public_key = null;
using (Stream keyin = File.OpenRead(public_key_path))
{
using (Stream public_key_stream = PgpUtilities.GetDecoderStream(keyin))
{
PgpPublicKeyRingBundle public_key_bundle = new PgpPublicKeyRingBundle(public_key_stream);
foreach (PgpPublicKeyRing public_key_ring in public_key_bundle.GetKeyRings())
{
foreach (PgpPublicKey key in public_key_ring.GetPublicKeys())
{
long modified_key_id = key.KeyId & 0x00000000FFFFFFFF;
if (modified_key_id == m_KeyId)
{
public_key = key;
break;
}
}
}
if (public_key == null)
throw new Exception("The public key value is null");
}
return public_key;
}
}
private PgpSecretKey GetLastSecretKey(PgpSecretKeyRingBundle secret_key_ring_bundle)
{
IEnumerable pgpKeyRings = secret_key_ring_bundle.GetKeyRings();
return (from PgpSecretKeyRing kring in secret_key_ring_bundle.GetKeyRings()
select kring.GetSecretKeys().Cast<PgpSecretKey>().
LastOrDefault(k => k.IsSigningKey)).LastOrDefault(key => key != null);
}
}
如果您需要任何解释,请告诉我。