我有幸每周处理约 5 个 SSL CSR,在将它们交给我们的 CA 进行处理之前检查它们的有效性。我在 Ubuntu 机器上使用 OpenSSL 检查它们是否有效,测试诸如正确的 OU 名称、合理的 CN、密钥大小 >=2048 位等内容,因为我们的请求有时不正确。
前几天我收到了更新来自 IIS7 计算机的请求。我完全搞不清楚如何使用 OpenSSL 读取它。它是有效的,因为我的 CA 已经接受了它...
'file(1)' 表示它是“RFC1421 安全证书签名请求文本”,这就是我这里的 ~50% 的 CSR 所说的内容(其余的是“PEM 证书请求”)。
$ head iis7rcsr
-----BEGIN NEW CERTIFICATE REQUEST-----
MIIQsQYJKoZIhvcNAQcCoIIQojCCEJ4CAQExCzAJBgUrDgMCGgUAMIIJegYJKoZI
hvcNAQcBoIIJawSCCWcwggljMIIIzAIBADCB2zELMAkGA1UEBhMCTloxDTALBgNV
BBEMBDkwNTQxDjAMBgNVBAgMBU90YWdvMRAwDgYDVQQHDAdEdW5lZGluMRwwGgYD
...
...
openssl req
,其中读取 CSR(PKCS#10)无法理解它......
$ openssl req -in iis7rcsr -text
unable to load X509 request
5156:error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag:tasn_dec.c:1316:
5156:error:0D07803A:asn1 encoding routines:ASN1_ITEM_EX_D2I:nested asn1 error:tasn_dec.c:380:Type=X509_REQ_INFO
5156:error:0D08303A:asn1 encoding routines:ASN1_TEMPLATE_NOEXP_D2I:nested asn1 error:tasn_dec.c:748:Field=req_info, Type=X509_REQ
5156:error:0906700D:PEM routines:PEM_ASN1_read_bio:ASN1 lib:pem_oth.c:83:
本文由 Andreas Klein 在 MSDN 博客上发表表明 IIS7 续订 CSR 是一个 PKCS#7 容器,其中包含基于当前证书的 CSR 和签名...但我仍然无法读取它。
$ openssl pkcs7 -in iis7rcsr -text
unable to load PKCS7 object
6581:error:0906D06C:PEM routines:PEM_read_bio:no start line:pem_lib.c:650:Expecting: PKCS7
我可以使用“openssl base64”解码文件,在生成的二进制文件中,我可以看到类似于 CSR 的字符串,以及一些 CA 引用,这些引用肯定来自基于旧证书的签名。因此,容器(CSR,签名)的想法听起来很合理。
但我仍然找不到读取其中的 CSR 的方法!我尝试了很多方法,我不会在这里列出细节,但以下是我尝试过的变化的要点:pkcs12 pkcs7 PEM DER req x509 verify...
不幸的是,我无法在此处发布 CSR 本身。有人能帮我找出读取/验证此文件的方法吗?
答案1
这个 IIS7 续订请求的结构实际上非常优雅。它似乎从这样的前提开始:因为这是一个续订请求当前的证书,它需要证明请求来自正确的主机——即实际使用当前证书的主机拥有相关私钥。在互联网世界中,您可以通过以原始用户的身份向 CA 进行身份验证来证明您有权请求续订证书,而不是创建签名的 CSR。
为了证明发出续订请求的权利,IIS7 创建一个普通的 CSR(PKCS#10 对象),然后对其进行签名,并提供签名该密钥的证书。
- IIS7 更新 CSR
- PKCS#7 数据
- PKCS#10 数据(普通 CSR)
- 普通服务器证书
- 签发 CA 数据
- RSA 签名(我假设)
- PKCS#7 数据
使用openssl asn1parse -in iis7rcsr -i
查看文件结构,并将其与普通 CSR 进行比较。您应该在开头附近看到一个 OCTET STRING,位于标记为“:pkcs7-data”的对象中,这就是您需要提取以获取 CSR 的内容。
$ openssl asn1parse -in iis7rcsr -i
0:d=0 hl=4 l=4273 cons: SEQUENCE
4:d=1 hl=2 l= 9 prim: OBJECT :pkcs7-signedData
15:d=1 hl=4 l=4258 cons: cont [ 0 ]
19:d=2 hl=4 l=4254 cons: SEQUENCE
23:d=3 hl=2 l= 1 prim: INTEGER :01
26:d=3 hl=2 l= 11 cons: SET
28:d=4 hl=2 l= 9 cons: SEQUENCE
30:d=5 hl=2 l= 5 prim: OBJECT :sha1
37:d=5 hl=2 l= 0 prim: NULL
39:d=3 hl=4 l=2426 cons: SEQUENCE
43:d=4 hl=2 l= 9 prim: OBJECT :pkcs7-data
54:d=4 hl=4 l=2411 cons: cont [ 0 ]
58:d=5 hl=4 l=2407 prim: OCTET STRING [HEX DUMP]:3082096330820...
为了从这里获取实际的 PKCS#10 CSR,我们需要该偏移数字,在本例中为“58”。然后我们可以使用该偏移量来提取该对象的二进制版本:-
$ openssl asn1parse -in iis7rcsr -strparse 58 -out thecsr -noout
接下来我们可以使用 读取输出文件“thecsr” openssl req
,记得指定输入格式 DER。
$ openssl req -in thecsr -inform DER -text -noout
Certificate Request:
Data:
Version: 0 (0x0)
Subject: (normal CSR Subject: line, censored)
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
...
我可以将所有这些包装到一个没有临时文件的命令行中(但遗憾的是需要读取原始证书两次),只要我可以使用 Linux 来/proc/self/fd/
欺骗 openssl(它将使用文件描述符执行本机技巧来处理密码,但不是正常输出)。
$ openssl asn1parse -in iis7rcsr -strparse $(openssl asn1parse -in iis7rcsr | grep -A2 ':pkcs7-data'|tail -1|cut -d: -f1) -out /dev/stdout -noout | openssl req -inform DER -noout -text
Certificate Request:
Data:
Version: 0 (0x0)
Subject: (Subject: line censored again)
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public Key: (1024 bit)
Modulus (1024 bit):
...
这个长命令行直接相当于openssl req -in non-iis7rcsr -noout -text
我通常使用的简单命令行:-)
答案2
感谢 Jim 提供这些非常有用的信息,我在尝试更新 w2008/IIS7 服务器证书时遇到了完全相同的问题。
我只想补充一点。您可以使用以下命令直接提取 P10 格式的 CSR:
certutil -split iis7rcsr
(iis7rcsr 是您通过 IIS 管理器获得的 .csr)。然后,csr 将被提取到名为的文件中。blob0_1.p10
它是二进制格式 (DER),您可能必须使用以下命令将其编码为 base64:
certutil -encode blob0_1.p10 finalcsr.csr
不过,还有最后一个问题。然后我发现,使用 openssl 转储 .csr 内容时,续订过程会自动强制使用 1024 位密钥(即使服务器上为服务器证书创建的原始私钥长度为 2048 位)。看来您无法使用 IIS7 的续订过程强制使用 2048 位密钥。
唯一好的选择似乎是创建一个新的密钥/证书,而不是使用更新过程。