验证来自公共密钥的签名,自动检测BouncyCastle中的算法

时间:2019-03-18 14:41:29

标签: .net digital-signature bouncycastle public-key-encryption asn.1

我的问题是:如何编写我的签名验证函数以与公钥算法无关?

我正在使用.Net的BouncyCastle库(v1.8.4)。我试图在不事先知道算法的情况下验证签名(但其标识将嵌入在公钥中)。

我需要验证字节流的签名,并且已经获得了PEM格式的公钥:

-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE7t7Uo4NB7kjqPGMzdXbBI66gy8rz
oYvRatFPTGsdS9lCru6imfdMclcr/hCkxHgfgz0ewmKqEjWK8EjZczUCEA==
-----END PUBLIC KEY-----

我希望它能通知ASN.1流中的算法,在此示例中,其解析如下:

$ openssl asn1parse -i -in pubkey.pem
    0:d=0  hl=2 l=  89 cons: SEQUENCE
    2:d=1  hl=2 l=  19 cons:  SEQUENCE
    4:d=2  hl=2 l=   7 prim:   OBJECT            :id-ecPublicKey
   13:d=2  hl=2 l=   8 prim:   OBJECT            :prime256v1
   23:d=1  hl=2 l=  66 prim:  BIT STRING

在这种情况下,算法是prime256v1(secp256k1等),但我事先不知道它是什么。目前,我的代码如下:

Private Function SignatureChecks(data() as Byte, pubkey as String, signature as String) As Boolean

    Dim keypars As Org.BouncyCastle.Crypto.AsymmetricKeyParameter 'impements ICipherParameters

    'Read and parse the PEM file into the proper object
    Dim pubkeybytes = Encoding.ASCII.GetBytes(pubkey)
    Using pubkeystream = New MemoryStream(pubkeybytes)
        Using reader = New StreamReader(pubkeystream)
            Dim pemrd = New PemReader(reader)
            'Now this is the decoded PEM for the public key
            keypars = pemrd.ReadObject()
        End Using
    End Using

    Dim signer As ISigner

    '*************************************************************
    'Currently this is hardwired: how can I make this intelligent?
    '*************************************************************
    signer = SignerUtilities.GetSigner("SHA-256withECDSA")

    'Init the signer with the public key
    signer.Init(False, keypars)
    'Appends the data to be verified in the SHA block buffer
    signer.BlockUpdate(data, 0, data.Length)

    'Get the bytes from the signature
    Dim sigbytes = Convert.FromBase64String(signature)

    Return signer.VerifySignature(sigbytes)

End Function

只要使用secp256k1算法进行签名,此代码就可以正常工作,但事实并非如此。我尝试过从AsymmetricKeyParameter对象(实际上是ECPublicKeyParameters)中提取信息,但是它的公共成员很少。但是,使用调试器确实会在对象的内部显示相关信息:诸如publicKeyParamSet = 1.2.840.10045.3.1.7,algorithm =“ EC”等值。

预先感谢

1 个答案:

答案 0 :(得分:0)

公钥中通知的prime256v1算法只是 encryption 算法(应该如此),而在任一密钥中均未指定 hash 算法公钥或签名。为了验证签名,参与者之间必须使用其他方式约定哈希函数(在这种情况下为SHA-256)。一个示例是CMS编码(以前称为PKCS#7),它是一种容器方法,可以嵌入检查签名有效性所需的所有信息。从公共密钥获取加密算法不足以执行任务。