ECDSA签名 - 使用密钥的结论是否可能?

时间:2017-04-09 13:04:15

标签: c# .net ecdsa .net-standard-1.6 .net-4.7

我注意到如果我使用ECDsa.SignData方法,我总会得到不同的ECDSA签名。

所以我想知道是否有可能从ECDSA签名到使用过的密钥?

如果Alice向Bob1和Bob2发送消息,Eve能否在没有公众的情况下确定签名来自同一个发件人?

public static byte[] SignData(KeyPair privateKeyPair, byte[] data)
{
    var ecDsa = ECDsa.Create(ECCurve.NamedCurves.brainpoolP320r1);
    ecDsa.ImportParameters(privateKeyPair.CreateECParameters());
    return ecDsa.SignData(data, HashAlgorithmName.SHA512);
}

public static bool VerifyData(KeyPair signedKeyPair, byte[] data, byte[] signature)
{
    var ecDsa = ECDsa.Create(ECCurve.NamedCurves.brainpoolP320r1);
    ecDsa.ImportParameters(signedKeyPair.CreateECParameters());
    return ecDsa.VerifyData(data,signature, HashAlgorithmName.SHA512);
}

var plainMsg = Encoding.UTF8.GetBytes("Hello World");
var keyPair = BrainpoolKeyGenerator.CreateKeyPair(true);

var signature1 = SignData(keyPair, plainMsg);
var signature2 = SignData(keyPair, plainMsg);

Assert.That(signature1,Is.Not.EquivalentTo(signature2), "Signature #1 and #2 are NOT equal");

Assert.That(VerifyData(keyPair.ExportPublicKey(), plainMsg, signature1), "Signature of #1 is valid");
Assert.That(VerifyData(keyPair.ExportPublicKey(), plainMsg, signature2), "Signature of #2 is valid");

1 个答案:

答案 0 :(得分:1)

不,在同一数据上有两个ECDSA签名,并不表明它是由同一方签署了两次或两次不同的派对。

为了谈论ECDSA如何运作,我们需要一些快速(松散定义)的术语:

  • G,发电机,是曲线上的一个点。
    • 与曲线的私钥(d)相关联的公钥为d * G,使用曲线数学,我们将不在此处讨论。
    • 对于brainpoolP320r1,G值在RFC5639, section 3.5中分解为xy
  • n,曲线Order,是给定d G的最大合法值。
    • RFC5639调用此值q,但大多数其他内容都将其称为n

Wikipedia上有一个ECDSA细分,但公式的要点是:

  • 创建一个随机数k,以便0 < k < n
  • r是一个等于EC点k * G
  • 的X坐标的整数
  • z成为解释为数字的消息摘要(带有一些修剪/扩展名)
  • kInvkn的倒数相反(另请参阅Extended Euclidean Algorithm)。
  • s成为kInv * (z + (r * d)) mod n
  • 签名为(rs)。
    • 在.NET中,(r,s)值以IEEE P1363格式表示,这意味着前半部分为r,后半部分为s,其长度由曲线确定。

因此,签名的前半部分实际上是一个随机数。椭圆曲线密码学是基于这样一个事实:它很难计算Q / G(其中Q是公钥,也就是曲线上的一个点),因此从k恢复r很难。

签名的后半部分(s)是签名者密钥所涉及的唯一部分,但它会被k大量打败。

然后,签名验证算法会检查Qz'(验证者的z版本)是否与rs结合使用。如果没有,则没有迹象表明是否因为哈希/摘要错误或公钥错误。