ECDSA 签名 - 是否可以得出所用密钥的结论?
ECDSA signature - Is a conclusion to the used key possible?
我注意到,如果我使用 ECDsa.SignData
方法,我总是会得到不同的 ECDSA 签名。
所以我想知道是否可以从ECDSA签名推断出使用的密钥?
如果 Alice 向 Bob1 和 Bob2 发送消息,Eve 可以在没有来自 Alice 的 public 的情况下确定签名来自同一发送者吗?
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");
不,对同一数据有两个 ECDSA 签名并不能表明它是由同一方签名两次还是由两个不同的方签名。
为了讨论 ECDSA 的工作原理,我们需要一些快速(松散定义)的术语:
G
,生成器,是曲线上的一个点。
- 与曲线的私钥 (
d
) 关联的 public 密钥是 d * G
,使用曲线数学我们不会在这里讨论。
- 对于 brainpoolP320r1,G 值在 RFC5639, section 3.5 中分解为
x
和 y
。
n
,曲线顺序,是给定 G
的 d
的最大合法值。
- RFC5639 将此值称为
q
,但大多数其他内容都将其称为 n
。
Wikipedia 上有 ECDSA 细分,但公式的要点是:
- 创建一个随机数
k
使得 0 < k < n
r
是一个整数,等于EC点的X坐标k * G
- 设
z
为解释为数字的消息摘要(带有一些 trimming/extension)
- 设
kInv
为 k
模 n
的倒数(另见 Extended Euclidean Algorithm)。
- 设
s
为kInv * (z + (r * d)) mod n
- 签名为(
r
,s
)。
- 在.NET中,(r, s)值以IEEE P1363格式表示,即前半部分为
r
,后半部分为s
,它们的长度由曲线.
所以,签名的前半部分实际上是一个随机数。椭圆曲线密码学基于这样一个事实,即很难计算 Q / G
(其中 Q 是 public 密钥,也就是曲线上的一个点),因此从 [=22= 恢复 k
]很难。
签名的后半部分 (s
) 是唯一涉及签名者密钥的部分,但它被 k
打败了很多。
签名验证算法然后检查是否 Q
和 z'
(z
的验证者版本),结合 r
和 s
进行配方平衡。如果不是,则没有迹象表明是因为 hash/digest 错误还是 public 键错误。
我注意到,如果我使用 ECDsa.SignData
方法,我总是会得到不同的 ECDSA 签名。
所以我想知道是否可以从ECDSA签名推断出使用的密钥?
如果 Alice 向 Bob1 和 Bob2 发送消息,Eve 可以在没有来自 Alice 的 public 的情况下确定签名来自同一发送者吗?
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");
不,对同一数据有两个 ECDSA 签名并不能表明它是由同一方签名两次还是由两个不同的方签名。
为了讨论 ECDSA 的工作原理,我们需要一些快速(松散定义)的术语:
G
,生成器,是曲线上的一个点。- 与曲线的私钥 (
d
) 关联的 public 密钥是d * G
,使用曲线数学我们不会在这里讨论。 - 对于 brainpoolP320r1,G 值在 RFC5639, section 3.5 中分解为
x
和y
。
- 与曲线的私钥 (
n
,曲线顺序,是给定G
的d
的最大合法值。- RFC5639 将此值称为
q
,但大多数其他内容都将其称为n
。
- RFC5639 将此值称为
Wikipedia 上有 ECDSA 细分,但公式的要点是:
- 创建一个随机数
k
使得0 < k < n
r
是一个整数,等于EC点的X坐标k * G
- 设
z
为解释为数字的消息摘要(带有一些 trimming/extension) - 设
kInv
为k
模n
的倒数(另见 Extended Euclidean Algorithm)。 - 设
s
为kInv * (z + (r * d)) mod n
- 签名为(
r
,s
)。- 在.NET中,(r, s)值以IEEE P1363格式表示,即前半部分为
r
,后半部分为s
,它们的长度由曲线.
- 在.NET中,(r, s)值以IEEE P1363格式表示,即前半部分为
所以,签名的前半部分实际上是一个随机数。椭圆曲线密码学基于这样一个事实,即很难计算 Q / G
(其中 Q 是 public 密钥,也就是曲线上的一个点),因此从 [=22= 恢复 k
]很难。
签名的后半部分 (s
) 是唯一涉及签名者密钥的部分,但它被 k
打败了很多。
签名验证算法然后检查是否 Q
和 z'
(z
的验证者版本),结合 r
和 s
进行配方平衡。如果不是,则没有迹象表明是因为 hash/digest 错误还是 public 键错误。