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

How can I verify signature for open PGP using BouncyCastle

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

  1. 我正在使用 C#
  2. 我有公钥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。

我检查了很多资源但没有成功。据我了解,我需要将 public 密钥和签名传递给某些验证方法。

也不清楚我是否必须将字符串格式的给定 public 键转换为一些适当的 public 键对象。如果我必须type是什么?我试图将其转换为 RsaKeyParameters 但收到有关 public 键上不适当块的错误消息。

目前我有以下代码

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

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

  1. 定义public键
  2. 将publicket转换为PgPPublicKey
  3. 获取 PgpSignature 对象
  4. 验证签名

要验证签名,您需要已签名的原始数据。

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();
    }
}