【问题标题】:C# Sign Data with SHA-256withECDSA using BouncyCastle produce different Signature everytimeC# 使用 BouncyCastle 使用 SHA-256withECDSA 签名数据每次都会产生不同的签名
【发布时间】:2018-04-17 23:52:00
【问题描述】:

我正在关注tutorial 使用 SHA-256withECDSA 对数据进行签名。

使用相同的私钥和消息,每次生成不同的签名结果。我所做的唯一更改是返回 Base64 编码字符串而不是 Base58

每次都应该是同一个签名吗?

public static string GetSignature(string privateKey, string message)

{

    var curve = SecNamedCurves.GetByName("secp256k1");

    var domain = new ECDomainParameters(curve.Curve, curve.G, curve.N, curve.H);
    var keyParameters = new

            BC.Crypto.Parameters.ECPrivateKeyParameters(new BC.Math.BigInteger(privateKey),

            domain);

    ISigner signer = SignerUtilities.GetSigner("SHA-256withECDSA");

    signer.Init(true, keyParameters);

    signer.BlockUpdate(Encoding.ASCII.GetBytes(message), 0, Encoding.ASCII.GetBytes(message).Length);

    var signature = signer.GenerateSignature();

    return Convert.ToBase64String(signature);

}

示例结果

MEQCIB0rqb8Dbrh+e2akoCVJaUS4tyJYqfRf8vdz/W2fUOomAiB3D2BaMYjwSgKRQyTd/W+YEn+wT0I4dq1hmgBfe/Sh7g==

MEUCIQDsWxG8Zr7MCemgGylAN+Y32qJYuDmqZMpaPwxTKosJ3AIgE3oSsBjcua/aCvfNXiMfcUM9U92p9aRlAIEopw/wvd0=

MEYCIQCjQ0EDHVFhASuUSPnCGjCb0O1sq3Op+aAl01afjIVviQIhAOnGyGN9cKswFn97de0o/Im9Hswo6AdnLhKIZSUcYbDY

MEYCIQCAqcHyhRcbLtuyimJ4XCHvJcz0p0Wd7FgJ1+07sOsC/gIhAKYwlhRv98C/3XeZE1TujkB9qMn2C99GaguJoWng9+2y

MEUCIQD7ObA0n0JpRNQDe+3udpeKGEk79KsrjHsjv/4Wlj2bigIgZERRSQBEN91HTJHqn+prlwSCKUT4AJx061Gi0tv8Xuw=

【问题讨论】:

标签: c# bouncycastle sha256 ecdsa


【解决方案1】:

所以答案是:它应该是不确定的——每次都不一样

https://en.wikipedia.org/wiki/Nondeterministic_algorithm

【讨论】:

    【解决方案2】:

    如果你想要确定性,你可以试试这个

    public string GetSignature(string privateKey, string message)
    {
        var curve = SecNamedCurves.GetByName("secp256k1");
        var domain = new ECDomainParameters(curve.Curve, curve.G, curve.N, curve.H);
        var keyParameters = new ECPrivateKeyParameters(new BigInteger(privateKey, 16), domain);
    
        var signer = new ECDsaSigner(new HMacDsaKCalculator(new Sha256Digest()));
        signer.Init(true, keyParameters);
    
        var signature = signer.GenerateSignature(Encoding.UTF8.GetBytes(message));
    
        var r = signature[0];
        var s = signature[1];
    
        var otherS = curve.Curve.Order.Subtract(s);
    
        if (s.CompareTo(otherS) == 1)
        {
            s = otherS;
        }
    
        var derSignature = new DerSequence
        (
            new DerInteger(new BigInteger(1, r.ToByteArray())), 
            new DerInteger(new BigInteger(1, s.ToByteArray()))
        )
        .GetDerEncoded();
    
        return Convert(derSignature);
    }
    
    public bool VerifySignature(string message, string publicKey, string signature)
    {
        var curve = SecNamedCurves.GetByName("secp256k1");
        var domain = new ECDomainParameters(curve.Curve, curve.G, curve.N, curve.H);
        var publicKeyBytes = Convert(publicKey);
        var q = curve.Curve.DecodePoint(publicKeyBytes);
        var keyParameters = new ECPublicKeyParameters(q, domain);
    
        var verifier = new ECDsaSigner();
        verifier.Init(false, keyParameters);
    
        Asn1InputStream decoder = new Asn1InputStream(Convert(signature));
        DerInteger r, s;
        try
        {
            DerSequence seq = (DerSequence)decoder.ReadObject();
            r = (DerInteger)seq[0];
            s = (DerInteger)seq[1];
        }
        finally
        {
            decoder.Close();
        }
    
        var rp = r.PositiveValue;
        var sp = s.PositiveValue;
    
        return verifier.VerifySignature(Encoding.UTF8.GetBytes(message), rp, sp);
    }
    
    public string Convert(byte[] input)
    {
        return string.Concat(input.Select(x => x.ToString("x2")));
    }
    
    public byte[] Convert(string input)
    {
        if (input.StartsWith("0x")) input = input.Remove(0, 2);
    
        return Enumerable.Range(0, input.Length / 2).Select(x => System.Convert.ToByte(input.Substring(x * 2, 2), 16)).ToArray();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-08-01
      • 1970-01-01
      • 2012-02-08
      • 1970-01-01
      • 2012-01-20
      • 2017-06-29
      • 1970-01-01
      • 2014-07-26
      相关资源
      最近更新 更多