OpenSSL 验证失败,找不到根证书
OpenSSL verify fails, can't find root certificate
重要提示:我下面问题中验证证书的方法不正确,会导致误报和漏报。正确方法见我的回答。
我正在测试我编写的用于测试我们环境中所有证书的工具,并且我 运行 遇到了 OpenSSL 似乎无法识别特定 GoDaddy 的问题根证书。
错误文本:
$ openssl verify -CAfile bundle.txt cert.txt
cert.txt: C = US, ST = Arizona, L = Scottsdale, O = "GoDaddy.com, Inc.", CN = Go Daddy Root Certificate Authority - G2
error 2 at 2 depth lookup:unable to get issuer certificate
但那个证书肯定在 /etc/pki/tls/certs/ca-bundle.crt
和 ca-bundle.trusted.crt
中。我已手动验证 x509v3 扩展中的 Issuer 和 Subject 密钥与受信任捆绑包中的 KeyID D2:C4:B0:D2:91:D4:4C:11:71:B3:61:CB:3D:A1:FE:DD:A8:6A:D4:E3
匹配。
我是不是漏掉了什么?
证书详情:
Certificate:
Issuer: C=US, ST=Arizona, L=Scottsdale, O=GoDaddy.com, Inc., OU=http://certs.godaddy.com/repository/, CN=Go Daddy Secure Certificate Authority - G2
X509v3 Subject Key Identifier:
28:3C:0E:1A:82:3E:7F:22:A6:DD:22:8C:45:78:BF:F6:40:47:4F:8A
X509v3 Authority Key Identifier:
keyid:40:C2:BD:27:8E:CC:34:83:30:A2:33:D7:FB:6C:B3:F0:B4:2C:80:CE
Bundle1:
Subject: C=US, ST=Arizona, L=Scottsdale, O=GoDaddy.com, Inc., OU=http://certs.godaddy.com/repository/, CN=Go Daddy Secure Certificate Authority - G2
Issuer: C=US, ST=Arizona, L=Scottsdale, O=GoDaddy.com, Inc., CN=Go Daddy Root Certificate Authority - G2
X509v3 Subject Key Identifier:
40:C2:BD:27:8E:CC:34:83:30:A2:33:D7:FB:6C:B3:F0:B4:2C:80:CE
X509v3 Authority Key Identifier:
keyid:3A:9A:85:07:10:67:28:B6:EF:F6:BD:05:41:6E:20:C1:94:DA:0F:DE
Bundle2:
Subject: C=US, ST=Arizona, L=Scottsdale, O=GoDaddy.com, Inc., CN=Go Daddy Root Certificate Authority - G2
Issuer: C=US, O=The Go Daddy Group, Inc., OU=Go Daddy Class 2 Certification Authority
X509v3 Subject Key Identifier:
3A:9A:85:07:10:67:28:B6:EF:F6:BD:05:41:6E:20:C1:94:DA:0F:DE
X509v3 Authority Key Identifier:
keyid:D2:C4:B0:D2:91:D4:4C:11:71:B3:61:CB:3D:A1:FE:DD:A8:6A:D4:E3
Trusted:
Subject: C=US, O=The Go Daddy Group, Inc., OU=Go Daddy Class 2 Certification Authority
X509v3 Subject Key Identifier:
D2:C4:B0:D2:91:D4:4C:11:71:B3:61:CB:3D:A1:FE:DD:A8:6A:D4:E3
X509v3 Authority Key Identifier:
keyid:D2:C4:B0:D2:91:D4:4C:11:71:B3:61:CB:3D:A1:FE:DD:A8:6A:D4:E3
DirName:/C=US/O=The Go Daddy Group, Inc./OU=Go Daddy Class 2 Certification Authority
serial:00
编辑
要添加到正在运行的 WTFery,使用 openssl s_client
打开到有问题的服务器的连接显示证书验证正常。
$ openssl s_client -servername www.foo.com -connect www.foo.com:443
Certificate chain
0 s:/OU=Domain Control Validated/CN=*.foo.com
i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.com/repository//CN=Go Daddy Secure Certificate Authority - G2
1 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.com/repository//CN=Go Daddy Secure Certificate Authority - G2
i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certificate Authority - G2
2 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certificate Authority - G2
i:/C=US/O=The Go Daddy Group, Inc./OU=Go Daddy Class 2 Certification Authority
...yadda yadda yadda...
Verify return code: 0 (ok)
如果您指定 -CAfile
openssl 只检查给定文件的颁发者,在您的情况下可能只包含中间证书。
openssl verify
标志的命名可能有点违反直觉,我找到的文档 none 对解决这个问题做了很多工作。正如 x539 所涉及的那样,我错误地使用了 -CAfile
选项,此外我还缺少用于指定中间证书的 -untrusted
选项。
我发现大多数证书通过验证的原因是大多数 CA 已经开始在 CA 捆绑包中包含根证书,并且 -CAfile
选项本质上定义了哪些内容应该包含受信任的部分链,包括根证书。在中间包不包含根的情况下,我最初的不正确验证方法失败了。
现在我误以为 -untrusted
暗示了 "never use these certificates!" 之类的东西,而是旨在指定一个不可信的证书链,这些证书会返回 [=32] 中的根=] -CAfile
束。
因此正确通过使用其中间证书[s]和受信任的根包来验证证书的方法是:
openssl verify -CAfile /etc/pki/tls/certs/ca-bundle.crt -untrusted bundle.crt certificate.crt
重要提示:我下面问题中验证证书的方法不正确,会导致误报和漏报。正确方法见我的回答。
我正在测试我编写的用于测试我们环境中所有证书的工具,并且我 运行 遇到了 OpenSSL 似乎无法识别特定 GoDaddy 的问题根证书。
错误文本:
$ openssl verify -CAfile bundle.txt cert.txt
cert.txt: C = US, ST = Arizona, L = Scottsdale, O = "GoDaddy.com, Inc.", CN = Go Daddy Root Certificate Authority - G2
error 2 at 2 depth lookup:unable to get issuer certificate
但那个证书肯定在 /etc/pki/tls/certs/ca-bundle.crt
和 ca-bundle.trusted.crt
中。我已手动验证 x509v3 扩展中的 Issuer 和 Subject 密钥与受信任捆绑包中的 KeyID D2:C4:B0:D2:91:D4:4C:11:71:B3:61:CB:3D:A1:FE:DD:A8:6A:D4:E3
匹配。
我是不是漏掉了什么?
证书详情:
Certificate:
Issuer: C=US, ST=Arizona, L=Scottsdale, O=GoDaddy.com, Inc., OU=http://certs.godaddy.com/repository/, CN=Go Daddy Secure Certificate Authority - G2
X509v3 Subject Key Identifier:
28:3C:0E:1A:82:3E:7F:22:A6:DD:22:8C:45:78:BF:F6:40:47:4F:8A
X509v3 Authority Key Identifier:
keyid:40:C2:BD:27:8E:CC:34:83:30:A2:33:D7:FB:6C:B3:F0:B4:2C:80:CE
Bundle1:
Subject: C=US, ST=Arizona, L=Scottsdale, O=GoDaddy.com, Inc., OU=http://certs.godaddy.com/repository/, CN=Go Daddy Secure Certificate Authority - G2
Issuer: C=US, ST=Arizona, L=Scottsdale, O=GoDaddy.com, Inc., CN=Go Daddy Root Certificate Authority - G2
X509v3 Subject Key Identifier:
40:C2:BD:27:8E:CC:34:83:30:A2:33:D7:FB:6C:B3:F0:B4:2C:80:CE
X509v3 Authority Key Identifier:
keyid:3A:9A:85:07:10:67:28:B6:EF:F6:BD:05:41:6E:20:C1:94:DA:0F:DE
Bundle2:
Subject: C=US, ST=Arizona, L=Scottsdale, O=GoDaddy.com, Inc., CN=Go Daddy Root Certificate Authority - G2
Issuer: C=US, O=The Go Daddy Group, Inc., OU=Go Daddy Class 2 Certification Authority
X509v3 Subject Key Identifier:
3A:9A:85:07:10:67:28:B6:EF:F6:BD:05:41:6E:20:C1:94:DA:0F:DE
X509v3 Authority Key Identifier:
keyid:D2:C4:B0:D2:91:D4:4C:11:71:B3:61:CB:3D:A1:FE:DD:A8:6A:D4:E3
Trusted:
Subject: C=US, O=The Go Daddy Group, Inc., OU=Go Daddy Class 2 Certification Authority
X509v3 Subject Key Identifier:
D2:C4:B0:D2:91:D4:4C:11:71:B3:61:CB:3D:A1:FE:DD:A8:6A:D4:E3
X509v3 Authority Key Identifier:
keyid:D2:C4:B0:D2:91:D4:4C:11:71:B3:61:CB:3D:A1:FE:DD:A8:6A:D4:E3
DirName:/C=US/O=The Go Daddy Group, Inc./OU=Go Daddy Class 2 Certification Authority
serial:00
编辑
要添加到正在运行的 WTFery,使用 openssl s_client
打开到有问题的服务器的连接显示证书验证正常。
$ openssl s_client -servername www.foo.com -connect www.foo.com:443
Certificate chain
0 s:/OU=Domain Control Validated/CN=*.foo.com
i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.com/repository//CN=Go Daddy Secure Certificate Authority - G2
1 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.com/repository//CN=Go Daddy Secure Certificate Authority - G2
i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certificate Authority - G2
2 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certificate Authority - G2
i:/C=US/O=The Go Daddy Group, Inc./OU=Go Daddy Class 2 Certification Authority
...yadda yadda yadda...
Verify return code: 0 (ok)
如果您指定 -CAfile
openssl 只检查给定文件的颁发者,在您的情况下可能只包含中间证书。
openssl verify
标志的命名可能有点违反直觉,我找到的文档 none 对解决这个问题做了很多工作。正如 x539 所涉及的那样,我错误地使用了 -CAfile
选项,此外我还缺少用于指定中间证书的 -untrusted
选项。
我发现大多数证书通过验证的原因是大多数 CA 已经开始在 CA 捆绑包中包含根证书,并且 -CAfile
选项本质上定义了哪些内容应该包含受信任的部分链,包括根证书。在中间包不包含根的情况下,我最初的不正确验证方法失败了。
现在我误以为 -untrusted
暗示了 "never use these certificates!" 之类的东西,而是旨在指定一个不可信的证书链,这些证书会返回 [=32] 中的根=] -CAfile
束。
因此正确通过使用其中间证书[s]和受信任的根包来验证证书的方法是:
openssl verify -CAfile /etc/pki/tls/certs/ca-bundle.crt -untrusted bundle.crt certificate.crt