【问题标题】:OpenSSL generates non-deterministic signature on CSR using P-256 or P-384 key, but not RSA key?OpenSSL 使用 P-256 或 P-384 密钥在 CSR 上生成非确定性签名,而不是 RSA 密钥?
【发布时间】:2019-12-21 05:59:47
【问题描述】:

当我使用openssl 的命令行生成一个 RSA-2048 密钥对,然后使用相同的私钥为相同的域名构造两个证书签名请求 (CSR) 时,我得到了相同的输出。

$ openssl genrsa -f4 -out rsa.key | head -1
Generating RSA private key, 2048 bit long modulus
$ openssl req -new -sha256 -key rsa.key -out rsa1.csr -subj "/CN=example.com"
$ openssl req -new -sha256 -key rsa.key -out rsa2.csr -subj "/CN=example.com"
$ diff rsa1.csr rsa2.csr

但是,当我生成一个椭圆曲线 (P-256) 密钥对并使用相同的私钥为相同的域名创建两个 CSR 时,我得到两个不同的输出!

$ openssl ecparam -genkey -name prime256v1 -noout -out p256.key
$ openssl req -new -sha256 -key p256.key -out ec1.csr -subj "/CN=example.com"
$ openssl req -new -sha256 -key p256.key -out ec2.csr -subj "/CN=example.com"
$ diff -U999 ec1.csr ec2.csr 
--- ec1.csr 2019-08-14 12:20:55.000000000 -0400
+++ ec2.csr 2019-08-14 12:20:59.000000000 -0400
@@ -1,7 +1,7 @@
 -----BEGIN CERTIFICATE REQUEST-----
-MIHRMHgCAQAwFjEUMBIGA1UEAwwLZXhhbXBsZS5jb20wWTATBgcqhkjOPQIBBggq
+MIHPMHgCAQAwFjEUMBIGA1UEAwwLZXhhbXBsZS5jb20wWTATBgcqhkjOPQIBBggq
 hkjOPQMBBwNCAASKkrbzoJCjHgvI95U1ZYPG5AQUtN+ImrutI2KNAne/BvktGaHW
-ep2CEc5bliuYzxeC68cUG0MBmDrLZbRwaMS7oAAwCgYIKoZIzj0EAwIDSQAwRgIh
-AO1VziY7sHIKNFvCQnm+g7fguFSPoopHw+Jh3CKpjTKYAiEAmvlilKQkiN134T07
-LCDWfF/IlGeWv6nv1VhgsD3SEBU=
+ep2CEc5bliuYzxeC68cUG0MBmDrLZbRwaMS7oAAwCgYIKoZIzj0EAwIDRwAwRAIg
+AxHKjgwyXbeMqWK8XF/F6KztweW/tpY1U55pXyHeKgECID9jgdAQp7FetjbRGY7A
+GY0Y37x8XY5O3o5rEZSnsA1C
 -----END CERTIFICATE REQUEST-----

这不是一次性的。我使用这个 P-256 密钥生成 1000 个 CSR,我得到 1000 个不同的输出。我使用这个 RSA-2048 密钥生成 1000 个 CSR,得到 1000 个相同的输出。

$ for i in `seq 1 1000`; do openssl req -new -sha256 -key p256.key -out ec$i.csr -subj "/CN=example.com"; done
real    0m8.147s
user    0m5.972s
sys     0m1.810s
$ md5sum ec*.csr | cut -f 1 -d ' ' | sort | uniq | wc -l
1000

$ time for i in `seq 1 1000`; do openssl req -new -sha256 -key rsa.key -out rsa$i.csr -subj "/CN=example.com"; done
real    0m43.940s
user    0m41.386s
sys     0m2.049s
$ md5sum rsa*.csr | cut -f 1 -d ' ' | sort | uniq | wc -l
1

这里到底发生了什么?有什么方法可以强制 OpenSSL 生成可重现的输出?有什么理由我不希望 OpenSSL 生成可重现的输出?

我有什么理由希望 OpenSSL 在使用 RSA 密钥时生成可重现的输出,但在使用 EC 密钥时


我应该补充一点,我使用 https://certlogik.com/decoder/ 来查看正在生成的 CSR,它们看起来与最后的 BIT STRING 完全相同除了,我认为应该是SHA-256 签名?

我还看到 P-384 键发生了同样的不确定性:

$ openssl ecparam -genkey -name secp384r1 -noout -out p384.key
$ openssl req -new -sha256 -key p384.key -out ec1.csr -subj "/CN=example.com"
$ openssl req -new -sha256 -key p384.key -out ec2.csr -subj "/CN=example.com"
$ cmp ec1.csr ec2.csr 
ec1.csr ec2.csr differ: char 275, line 5

【问题讨论】:

  • 啊,我发现 crypto.stackexchange.com/questions/851/… 暗示非确定性是任何由 EC 密钥签名的有意特征,这真的太糟糕了。这个问题可能只是归结为那个问题的副本。但我不太明白,不能说它肯定是重复的。
  • RSA PKCS#1(v1.5) 签名是确定性的。 RSA PSS 签名不是(随机数据被注入),并且 ECDSA(和 DSA)始终是非确定性的(以确定性 DSA RFC 为模)。只是算法的性质。

标签: openssl rsa elliptic-curve csr libssl


【解决方案1】:

标准 ECDSA 签名本质上是不确定的。这是算法的基本特征。另一方面,RSA 签名是确定性的。所以这就是您看到这些类型的键之间差异的原因。

有一个 RFC,它描述了生成确定性 ECDSA 签名的过程(请参阅RFC6979)。但是 OpenSSL 目前不支持它。有一个开放的拉取请求添加了该功能here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多