我正在关注此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=
答案 0 :(得分:1)
所以答案是:它应该是非确定性的 - 每次都是不同的
答案 1 :(得分:0)
如果您要确定性,可以尝试一下
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();
}