如何使用公共密钥使用c#使用bouncycastle解密pgp文件

时间:2015-12-15 15:42:42

标签: c# vb.net bouncycastle pgp

我正在寻找一个代码示例,它将向我展示如何使用bouncy castle使用公钥解密pgp文件。我有一些代码可以解密用我提供给用户的密钥加密的文件,但是因为我只有来自客户端的公钥而且我的代码不同。

所以对此有任何帮助将不胜感激。 :)

JD

2 个答案:

答案 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); 
        }
    }

如果您需要任何解释,请告诉我。