【问题标题】:How to chain a SSL server certificate with the intermediate and root CA certificates?如何将 SSL 服务器证书与中间 CA 证书和根 CA 证书链接起来?
【发布时间】:2015-04-03 17:29:29
【问题描述】:

我以为我明白了,但它不起作用!

我读到了http://binblog.info/2010/02/02/lengthy-chains/,这是我找到的最简洁的解释。

背景: Comodo 便宜的 PositiveSSL 服务器证书带有一个根证书和两个中间 CA 证书(我用 myserver.com 替换了我的 FQDN):

$ unzip ../myserver_com.commodo.certificate.zip 
Archive:  ../myserver_com.commodo.certificate.zip
 extracting: AddTrustExternalCARoot.crt  
 extracting: COMODORSAAddTrustCA.crt  
 extracting: COMODORSADomainValidationSecureServerCA.crt  
 extracting: myserver_com.crt           

请注意,字母顺序类似于从根 CA 到服务器证书的倒置证书链。根 CA 不是 Comodo,但这不是重点。

考虑以下输出:

openssl x509 -noout -subject -issuer -in myserver_com.crt 
subject= /OU=Domain Control Validated/OU=PositiveSSL/CN=myserver.com
issuer= /C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA

openssl x509 -noout -subject -issuer -in COMODORSADomainValidationSecureServerCA.crt 
subject= /C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA
issuer= /C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority

openssl x509 -noout -subject -issuer -in COMODORSAAddTrustCA.crt 
subject= /C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
issuer= /C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root

openssl x509 -noout -subject -issuer -in AddTrustExternalCARoot.crt 
subject= /C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root
issuer= /C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root

前一个证书的颁发者是后者的主体 - 直到来自 AddTrust AB 的根 CA 证书是自签名的。链条已完成。

验证单个证书给出:

$ openssl verify *.crt
AddTrustExternalCARoot.crt: OK
COMODORSAAddTrustCA.crt: OK
COMODORSADomainValidationSecureServerCA.crt: C = GB, ST = Greater Manchester, L = Salford, O = COMODO CA Limited, CN = COMODO RSA Domain Validation Secure Server CA
error 20 at 0 depth lookup:unable to get local issuer certificate
myserver_com.crt: OU = Domain Control Validated, OU = PositiveSSL, CN = myserver.com
error 20 at 0 depth lookup:unable to get local issuer certificate

前两个证书已经安装在服务器上,剩下两个证书要连接,但我还是把它们都链接了。

来自 RFC5246 https://www.rfc-editor.org/rfc/rfc5246#section-7.4.2

 certificate_list

 This is a sequence (chain) of certificates.  The sender's
 certificate MUST come first in the list.  Each following
 certificate MUST directly certify the one preceding it.  Because
 certificate validation requires that root keys be distributed
 independently, the self-signed certificate that specifies the root
 certificate authority MAY be omitted from the chain, under the
 assumption that the remote end must already possess it in order to
 validate it in any case.

当我以正确的方式链接证书时,证书被识别为 TLS 会话的服务器证书,但未经验证。

$ cat myserver_com.crt COMODORSADomainValidationSecureServerCA.crt COMODORSAAddTrustCA.crt AddTrustExternalCARoot.crt > chained.crt
$ openssl verify chained.crt 
chained.crt: OU = Domain Control Validated, OU = PositiveSSL, CN = das.email
error 20 at 0 depth lookup:unable to get local issuer certificate

当连接到服务器时

$ openssl s_client -crlf -connect myserver:465

证书被接受并且链被识别,但根证书未被识别为受信任,尽管它存在于 /etc/ssl/mozilla/ 中的受信任证书中。

我错过了什么?我可以简单地忽略命令行 openssl 工具中的错误吗?

【问题讨论】:

  • 这个问题似乎离题了,因为它与编程或开发无关。请参阅帮助中心的What topics can I ask about here。也许Super User 或Information Security Stack Exchange 会是一个更好的提问地点。
  • @jww 感谢您指出这一点——我想知道为什么没有人看过它——所以它确实似乎离题了。纽比,你看。我会考虑你的提示。老实说,我没有查看主题政策 - 我只是碰巧在这里找到了我所有未受过教育的业余服务器管理员问题的最佳答案。

标签: ssl openssl ssl-certificate x509


【解决方案1】:

openssl verify chained.crt 并没有像您想象的那样(直接)验证链;它从文件中读取一个(第一个)证书,并根据信任库对其进行验证。这里的第一个证书是您的服务器(叶)证书,由您的第一个中间(Comodo DV-server)颁发,它不在信任库中,因此查找失败。要(几乎)由 SSL 客户端对协议中收到的链进行验证,请执行以下操作:

openssl verify -purpose sslclient -untrusted restofchain myserver.crt 

其中restofchain 是一个至少包含链中其他证书的文件 除了根可以省略,所以在你的情况下 两个 Comodo 中间证书和可选的 AddTrust 根证书。 openssl 不要求它们像 5246 那样处于向上的顺序, 但如果是的话也没关系。事实上,如果叶证书存在 在 this 文件中,它将被忽略,因此您可以使用 chained.crt。

对于s_client,我不确定您所说的“证书被接受......但根证书未被识别为受信任”是什么意思。如果 s_client 调用的 libssl-client 代码成功验证接收到的链,那么用于该链的根必须在本地信任库中,因为这是 openssl 认为验证成功的唯一情况——至少通过 1.0.1,甚至在最近的 1.0.2 中,它仍然是默认值——但它从不输出“trusted”这个词。

一个可能的混淆来源:不像真正的客户端,例如浏览器或 Java 程序,如果接收到的证书/链没有验证,或者至少需要手动覆盖才能继续,就会中止连接,s_client 是一个测试无论证书状态如何,始终进行连接的工具。您必须专门查找验证错误(靠近输出顶部)和/或“验证返回码”(通常位于最底部)。

编辑 4/21:OpenSSL 到 1.0.2a 至少有一个错误; s_client(以及 s_server 和 s_time)实际上并没有使用默认的信任库,如果您没有指定 -CAfile 或 -CApath 参数,则它应该如此。见https://serverfault.com/questions/607233/how-to-make-openssl-s-client-using-default-ca;已为开发人员宣布修复,但除非您在发布和分发之前从头开始构建自己的版本,否则您需要明确指定 -CA* 参数,即使它看起来是多余的。

【讨论】:

  • "openssl verify chained.crt 并没有像您想象的那样(直接)验证链;它从文件中读取一个(第一个)证书并根据信任库验证它。这几乎解释了验证错误。我在-CAfile restchain.crt 中对链的其余部分进行了同样的尝试,这没关系。现在我对 s_client 错误的意思是:depth=3 C = SE, O = AddTrust AB, OU = AddTrust External TTP Network, CN = AddTrust External CA Root verify error:num=19:self signed certificate in certificate chain verify返回:0
  • 我的后一条评论有点难以阅读,几分钟后我无法编辑它......错误是verify error:num=19:self signed certificate in certificate chain,返回码是verify return: 0,所以也许没关系.自签名证书是 COMODO 的根 CA 证书,位于 /etc/ssl/certs/AddTrust_External_Root.pem
  • verify return 0 表示验证失败,verify error 19 at depth 3 (here) 表示更具体地说,接收到具有指示名称的根,但在信任库中未找到。您的问题表明您的默认信任库是 /etc/ssl/mozilla/ 但现在您说 /etc/ssl/certs/,您实际上使用的是不同的信任库吗?您针对某些默认信任库显示了 AddTrust*Root 文件的 verify OK,因此针对相同默认值的 s_client 也应该成功。这些都是在同一个系统上还是在不同的系统上?
  • /etc/ssl/certs/ 是信任库,它链接到 /usr/share/ca-certificates/mozilla/ - 抱歉,我以为我没记错,但混淆了路径。所以,只有一个信任库。
  • 我会问超级用户的问题。无论如何:我将问题浓缩为以下问题:为什么openssl不接受根CA证书,尽管默认情况下在Ubuntu服务器信任库中找到它?我收到来自 COMODO 的每封电子邮件的“AddTrustExternalCARoot.crt”,并在服务器上安装了“/etc/ssl/certs/AddTrust_External_Root.pem”。两者都是相同的 - 在连接到外壳之后。
猜你喜欢
  • 2021-01-17
  • 2019-11-15
  • 2015-11-01
  • 1970-01-01
  • 2021-07-22
  • 2013-07-23
  • 1970-01-01
  • 2021-12-18
  • 1970-01-01
相关资源
最近更新 更多