如何使用 OpenSSL 验证/读取 IIS7 SSL 续订 CSR

如何使用 OpenSSL 验证/读取 IIS7 SSL 续订 CSR

我有幸每周处理约 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 签名(我假设)

使用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 位密钥。

唯一好的选择似乎是创建一个新的密钥/证书,而不是使用更新过程。

相关内容