具有BouncyCastle和DSACryptoServiceProvider的等效DSA验证程序

时间:2016-03-29 09:15:04

标签: vb.net bouncycastle dsa

这两个函数应该是等价的,但VerifyBouncyCastle()对于VerifyDotNet()返回true的相同输入返回false(验证失败)。该消息是与.Net' DSACryptoServiceProvider.SignHash()签署的。 VerifyBouncyCastle()有什么问题导致它与.Net版本的行为不同?

.Net内置加密库:

Private Function VerifyDotNet(hash() As Byte, p() As Byte, q() As Byte, g() As Byte, y() As Byte, r() As Byte, s() As Byte) As Boolean

    'Public key
    Dim dotNetDSA As New DSACryptoServiceProvider()
    Dim dotNetParameters As New DSAParameters
    dotNetParameters.P = p
    dotNetParameters.Q = q
    dotNetParameters.G = g
    dotNetParameters.Y = y
    dotNetDSA.ImportParameters(dotNetParameters)

    'Signature
    Dim signature(39) As Byte
    Array.ConstrainedCopy(r, 0, signature, 0, 20)
    Array.ConstrainedCopy(s, 0, signature, 20, 20)

    'Verify
    Return dotNetDSA.VerifyHash(hash, "SHA1", signature)

End Function

BouncyCastle的:

Private Function VerifyBouncyCastle(hash() As Byte, p() As Byte, q() As Byte, g() As Byte, y() As Byte, r() As Byte, s() As Byte) As Boolean

    'Public key
    Dim pBigInt As New Org.BouncyCastle.Math.BigInteger(p)
    Dim qBigInt As New Org.BouncyCastle.Math.BigInteger(q)
    Dim gBigInt As New Org.BouncyCastle.Math.BigInteger(g)
    Dim yBigInt As New Org.BouncyCastle.Math.BigInteger(y)
    Dim bouncyParameters As New Org.BouncyCastle.Crypto.Parameters.DsaParameters(pBigInt, qBigInt, gBigInt)
    Dim bouncyPublicKey As New Org.BouncyCastle.Crypto.Parameters.DsaPublicKeyParameters(yBigInt, bouncyParameters)
    Dim bouncyDSA As New Org.BouncyCastle.Crypto.Signers.DsaSigner
    bouncyDSA.Init(False, bouncyPublicKey)

    'Signature
    Dim signatureR As New Org.BouncyCastle.Math.BigInteger(r)
    Dim signatureS As New Org.BouncyCastle.Math.BigInteger(s)

    'Verify
    Return bouncyDSA.VerifySignature(hash, signatureR, signatureS)

End Function

我已尝试撤消字节数组,并且还验证了BouncyCastle的Sha1Digest.DoFinal()为与.Net SHA1Managed.ComputeHash()相同的消息生成相同的哈希值用于生成签名的哈希。

1 个答案:

答案 0 :(得分:0)

BouncyCastle的公钥参数p,q,g,y的字节数组前导0而.Net不具备。因此,使用前导零填充以使BouncyCastle处理.Net关键参数。

Private Function VerifyBouncyCastle(hash() As Byte, p() As Byte, q() As Byte, g() As Byte, y() As Byte, r() As Byte, s() As Byte) As Boolean

    'Public key
    Dim bouncyCastleP(p.Length) As Byte
    Dim bouncyCastleQ(q.Length) As Byte
    Dim bouncyCastleG(g.Length) As Byte
    Dim bouncyCastleY(y.Length) As Byte
    Array.ConstrainedCopy(p, 0, bouncyCastleP, 1, p.Length)
    Array.ConstrainedCopy(q, 0, bouncyCastleQ, 1, q.Length)
    Array.ConstrainedCopy(g, 0, bouncyCastleG, 1, g.Length)
    Array.ConstrainedCopy(y, 0, bouncyCastleY, 1, y.Length)
    Dim pBigInt As New Org.BouncyCastle.Math.BigInteger(bouncyCastleP)
    Dim qBigInt As New Org.BouncyCastle.Math.BigInteger(bouncyCastleQ)
    Dim gBigInt As New Org.BouncyCastle.Math.BigInteger(bouncyCastleG)
    Dim yBigInt As New Org.BouncyCastle.Math.BigInteger(bouncyCastleY)
    Dim bouncyParameters As New Org.BouncyCastle.Crypto.Parameters.DsaParameters(pBigInt, qBigInt, gBigInt)
    Dim bouncyPublicKey As New Org.BouncyCastle.Crypto.Parameters.DsaPublicKeyParameters(yBigInt, bouncyParameters)

    'Signature
    Dim bouncyDSA As New Org.BouncyCastle.Crypto.Signers.DsaSigner
    bouncyDSA.Init(False, bouncyPublicKey)
    Dim signatureR As New Org.BouncyCastle.Math.BigInteger(r)
    Dim signatureS As New Org.BouncyCastle.Math.BigInteger(s)

    'Verify
    Return bouncyDSA.VerifySignature(hash, signatureR, signatureS)

End Function

或者,您可以使用Org.BouncyCastle.Security.DotNetUtilities.GetDsaPublicKey()将.Net公钥参数转换为BouncyCastle。