为什么 ECDSA 会为相同的数据生成不同的签名,而 RSA 不会?
Why does ECDSA produce different signatures for the same data, whereas RSA doesn't?
考虑以下使用 RSA 的代码...
示例:
byte[] raw = Encoding.Default.GetBytes("Hello, World!");
RSA key = RSA.Create();
for (int index = 0; index < 5; index++)
{
byte[] signed = key.SignData(raw, HashAlgorithmType.SHA256, RSASignaturePadding.Pkcs1);
string hashed = signed.ToSha256String();
Console.WriteLine(hashed);
}
输出:
043a718774c572bd8a25adbeb1bfcd5c0256ae11cecf9f9c3f925d0e52beaf89
043a718774c572bd8a25adbeb1bfcd5c0256ae11cecf9f9c3f925d0e52beaf89
043a718774c572bd8a25adbeb1bfcd5c0256ae11cecf9f9c3f925d0e52beaf89
043a718774c572bd8a25adbeb1bfcd5c0256ae11cecf9f9c3f925d0e52beaf89
043a718774c572bd8a25adbeb1bfcd5c0256ae11cecf9f9c3f925d0e52beaf89
现在考虑相同的代码,除了使用 ECDSA...
示例:
byte[] raw = Encoding.Default.GetBytes("Hello, World!");
ECDsa key = ECDsa.Create();
for (int index = 0; index < 5; index++)
{
byte[] signed = key.SignData(raw, HashAlgorithmType.SHA256);
string hashed = signed.ToSha256String();
Console.WriteLine(hashed);
}
输出:
043a718774c572bd8a25adbeb1bfcd5c0256ae11cecf9f9c3f925d0e52beaf89
a31fe9656fc8d3a459e623dc8204e6d0268f8df56d734dac3ca3262edb5db883
a871c47a7f48a12b38a994e48a9659fab5d6376f3dbce37559bcb617efe8662d
d7ef0a04f3c8055644677299a9414a75adcb15916eb48417416c9317ace2ff4f
779f5dd63960abda52a7da70464b92eedd47f84a8dffda2d672e6a99de1bab95
RSA 的签名输出符合我的预期; ECDSA,我没有。为什么ECDSA对相同的数据产生不同的签名?
ECDSA 的签名由 R 和 S 的组合组成,其中 R 是输入到 ECDSA 算法中的随机值,S 取决于该值。如果 R 是一个静态值,那么它将 allow an attacker to calculate the private key (!)(阅读文章:实际的随机值称为 k,R 是通过使用 k 对基点进行点乘来计算的)。
使用 PKCS#1 v1.5 填充的签名生成是确定性的这一事实使其成为奇数。实际上,带有 PSS 填充的 RSA 是使用显式盐随机化的,因此确定性行为与 RSA 没有任何关系;您甚至可以说这是不需要的 属性,因为它确实公开了有关已签名消息/数据的信息(给验证者以外的其他方)。
Elliptic Curve Digital Signature Algorithm (ECDSA), that is an adaptation of the classical DSA algorithm, relies on a cryptographically secure random number generator。例如:ECDSA 签名算法计算消息的哈希值,然后生成一个随机整数 k
并计算签名(一对整数 {R
, S
} )。 R
是从k
计算出来的,S
是用消息哈希+私钥+随机数k
计算出来的。因此,由于随机性,签名是 non-deterministic。
您可以试验椭圆曲线 here。
考虑以下使用 RSA 的代码...
示例:
byte[] raw = Encoding.Default.GetBytes("Hello, World!");
RSA key = RSA.Create();
for (int index = 0; index < 5; index++)
{
byte[] signed = key.SignData(raw, HashAlgorithmType.SHA256, RSASignaturePadding.Pkcs1);
string hashed = signed.ToSha256String();
Console.WriteLine(hashed);
}
输出:
043a718774c572bd8a25adbeb1bfcd5c0256ae11cecf9f9c3f925d0e52beaf89 043a718774c572bd8a25adbeb1bfcd5c0256ae11cecf9f9c3f925d0e52beaf89 043a718774c572bd8a25adbeb1bfcd5c0256ae11cecf9f9c3f925d0e52beaf89 043a718774c572bd8a25adbeb1bfcd5c0256ae11cecf9f9c3f925d0e52beaf89 043a718774c572bd8a25adbeb1bfcd5c0256ae11cecf9f9c3f925d0e52beaf89
现在考虑相同的代码,除了使用 ECDSA...
示例:
byte[] raw = Encoding.Default.GetBytes("Hello, World!");
ECDsa key = ECDsa.Create();
for (int index = 0; index < 5; index++)
{
byte[] signed = key.SignData(raw, HashAlgorithmType.SHA256);
string hashed = signed.ToSha256String();
Console.WriteLine(hashed);
}
输出:
043a718774c572bd8a25adbeb1bfcd5c0256ae11cecf9f9c3f925d0e52beaf89 a31fe9656fc8d3a459e623dc8204e6d0268f8df56d734dac3ca3262edb5db883 a871c47a7f48a12b38a994e48a9659fab5d6376f3dbce37559bcb617efe8662d d7ef0a04f3c8055644677299a9414a75adcb15916eb48417416c9317ace2ff4f 779f5dd63960abda52a7da70464b92eedd47f84a8dffda2d672e6a99de1bab95
RSA 的签名输出符合我的预期; ECDSA,我没有。为什么ECDSA对相同的数据产生不同的签名?
ECDSA 的签名由 R 和 S 的组合组成,其中 R 是输入到 ECDSA 算法中的随机值,S 取决于该值。如果 R 是一个静态值,那么它将 allow an attacker to calculate the private key (!)(阅读文章:实际的随机值称为 k,R 是通过使用 k 对基点进行点乘来计算的)。
使用 PKCS#1 v1.5 填充的签名生成是确定性的这一事实使其成为奇数。实际上,带有 PSS 填充的 RSA 是使用显式盐随机化的,因此确定性行为与 RSA 没有任何关系;您甚至可以说这是不需要的 属性,因为它确实公开了有关已签名消息/数据的信息(给验证者以外的其他方)。
Elliptic Curve Digital Signature Algorithm (ECDSA), that is an adaptation of the classical DSA algorithm, relies on a cryptographically secure random number generator。例如:ECDSA 签名算法计算消息的哈希值,然后生成一个随机整数 k
并计算签名(一对整数 {R
, S
} )。 R
是从k
计算出来的,S
是用消息哈希+私钥+随机数k
计算出来的。因此,由于随机性,签名是 non-deterministic。
您可以试验椭圆曲线 here。