如何使用BouncyCastle验证打开PGP的签名

时间:2018-01-17 11:25:19

标签: c# bouncycastle

如何使用BouncyCastle验证打开PGP的签名?

  1. 我正在使用C#
  2. 我有pulic key http://itransact.com/support/toolkit/html-connection/pgp.php
  3. 我使用BouncyCastle作为开放pgp库
  4. 我收到查询字符串中的签名。
  5. 根据指令(http://itransact.com/downloads/PCFullDocument-4.4.pdf p.145),算法是RSA。
  6. 我检查了很多资源但没有成功。据我所知,我需要将公钥和签名传递给某些验证方法。

    我还不清楚是否必须将字符串格式的给定公钥转换为某个适当的公钥对象。如果我必须type是什么?我试图将其转换为RsaKeyParameters,但收到有关公钥上不适当阻止的错误消息。

    目前我有以下代码

    private bool VerifyWithPublicKey(string data, byte[] sig)
        {
            RSACryptoServiceProvider rsa;
    
            using (var keyreader = new StringReader(publicKey))
            {
                    var pemReader = new PemReader(keyreader);
                    var y = (RsaKeyParameters)pemReader.ReadObject();
                    rsa = (RSACryptoServiceProvider)RSA.Create();
                    var rsaParameters = new RSAParameters();
    
                    rsaParameters.Modulus = y.Modulus.ToByteArray();
                    rsaParameters.Exponent = y.Exponent.ToByteArray();
                    rsa.ImportParameters(rsaParameters);
    
                    // compute sha1 hash of the data
                    var sha = new SHA1CryptoServiceProvider();
                    byte[] hash = sha.ComputeHash(Encoding.ASCII.GetBytes(data));
    
                    // This always returns false
                    return rsa.VerifyHash(hash, CryptoConfig.MapNameToOID("SHA1"), sig);
            }
    

1 个答案:

答案 0 :(得分:0)

使用RSA不是你的情况。你需要

  1. 定义公钥
  2. 将公共转换为PgPPublicKey
  3. 获取PgpSignature对象
  4. 验证签名
  5. 要验证签名,您需要签名的原始数据。

    public class iTransactVerifier
    {
        private const string PublicKey = @"-----BEGIN PGP PUBLIC KEY BLOCK-----
    Version: 4.5
    
    mQCNAjZu
    -----END PGP PUBLIC KEY BLOCK-----";
    
        public static bool Verify(string signature, string data)
        {
            var inputStream = ConvertStringToStream(signature);
    
            PgpPublicKey publicKey = ReadPublicKeyFromString();
            var stream = PgpUtilities.GetDecoderStream(inputStream);
    
            PgpObjectFactory pgpFact = new PgpObjectFactory(stream);
    
            PgpSignatureList sList = pgpFact.NextPgpObject() as PgpSignatureList;
            if (sList == null)
            {
                throw new InvalidOperationException("PgpObjectFactory could not create signature list");
            }
            PgpSignature firstSig = sList[0];
    
            firstSig.InitVerify(publicKey);
            firstSig.Update(Encoding.UTF8.GetBytes(data));
    
            var verified = firstSig.Verify();
            return verified;
        }
    
        ....
    
        private static PgpPublicKey ReadPublicKeyFromString()
        {
            var varstream = ConvertStringToStream(PublicKey);
            var stream = PgpUtilities.GetDecoderStream(varstream);
    
            PgpObjectFactory pgpFact = new PgpObjectFactory(stream);
            var keyRing = (PgpPublicKeyRing)pgpFact.NextPgpObject();
            return keyRing.GetPublicKey();
        }
    }