题 使用CLI工具显示远程SSL证书详细信息


在Chrome中,点击绿色HTTPS锁图标会打开一个包含证书详细信息的窗口:

enter image description here

当我尝试使用cURL时,我只获得了一些信息:

$ curl -vvI https://gnupg.org
* Rebuilt URL to: https://gnupg.org/
* Hostname was NOT found in DNS cache
*   Trying 217.69.76.60...
* Connected to gnupg.org (217.69.76.60) port 443 (#0)
* TLS 1.2 connection using TLS_DHE_RSA_WITH_AES_128_CBC_SHA
* Server certificate: gnupg.org
* Server certificate: Gandi Standard SSL CA
* Server certificate: UTN-USERFirst-Hardware
> HEAD / HTTP/1.1
> User-Agent: curl/7.37.1
> Host: gnupg.org
> Accept: */*

知道如何从命令行工具(cURL或其他)获取完整的证书信息?


128
2018-01-23 22:13




也可以看看 stackoverflow.com/questions/7885785/... - Vadzim
可能也取决于版本。我现在的 curl 与国旗 --verbose 显示完整的服务器证书内容。 - Patrick Mevzek


答案:


您应该能够将OpenSSL用于您的目的:

echo | openssl s_client -showcerts -servername gnupg.org -connect gnupg.org:443 2>/dev/null | openssl x509 -inform pem -noout -text

该命令连接到所需的网站,并将PEM格式的证书传输到另一个读取和解析详细信息的openssl命令。

(注意“多余” -servername 参数是必要的 openssl 通过SNI支持请求。)


183
2018-01-23 22:26



此命令似乎有错误: OpenSSL> openssl:Error: 'CONNECTED(00000003)' is an invalid command. - Adam Matan
@AdamMatan您是否在第二个管道后包含完整命令?错误消息看起来像第二个openssl调用最终以交互模式运行(即 openssl VS openssl x509 -inform pem -noout -text)。佩德罗所写的内容对我来说很好。 - Håkan Lindqvist
请注意,虽然s_client将打印整个链,但最后一个管道命令将仅打印有关第一个证书的信息。 - chutz
echo 本身相当于 echo '' ..它向stdout发送一个空字符串。 cat /dev/null | 也会工作,而且更加不言自明。 - hemp
如果你想知道的话 到期日,你可以更换 -text 同 -enddate,检查其他选项(openssl x509 help)。 - adriaan


简单解决方案

这是我的日常脚本:

curl --insecure -v https://www.google.com 2>&1 | awk 'BEGIN { cert=0 } /^\* SSL connection/ { cert=1 } /^\*/ { if (cert) print }'

输出:

* SSL connection using TLS1.2 / ECDHE_RSA_AES_128_GCM_SHA256
*    server certificate verification SKIPPED
*    server certificate status verification SKIPPED
*    common name: www.google.com (matched)
*    server certificate expiration date OK
*    server certificate activation date OK
*    certificate public key: RSA
*    certificate version: #3
*    subject: C=US,ST=California,L=Mountain View,O=Google Inc,CN=www.google.com
*    start date: Wed, 24 May 2017 17:39:15 GMT
*    expire date: Wed, 16 Aug 2017 17:13:00 GMT
*    issuer: C=US,O=Google Inc,CN=Google Internet Authority G2
*    compression: NULL
* ALPN, server accepted to use http/1.1
* Connection #0 to host www.google.com left intact

42
2018-01-15 13:23



对我不起作用,不包括开始/过期日期。 - Per Lundberg
由于最近卷曲的某些变化(介于49和52之间),因此根本不会显示有关证书的任何内容。 :( - Ross Presser
删除2>&1 - Jeshan Babooa
奇迹般有效!谢谢 :-) - Rahul Soni


取决于您想要的信息类型,但是:

openssl s_client -showcerts -connect gnupg.org:443

应该给你最多,虽然没有像Chrome那样可读的人类可读性。


17
2018-01-23 22:20



不幸的是,该命令以人类可读的格式呈现很少的证书数据。 - Håkan Lindqvist
我不同意之前的评论,这个命令告诉我我需要知道什么,并且非常有用。 +1回答。 - camdixon
如果您特别想要测试TLS 1.2,可以添加-tls1_2 - camdixon


nmap -p 443 --script ssl-cert gnupg.org

-p 443 指定仅扫描端口443。如果省略,将扫描所有端口,并显示找到的任何SSL服务的证书详细信息。该 --script ssl-cert 告诉你 Nmap脚本引擎 只运行 ssl-cert 脚本。从文档中,这个脚本“(r)获取服务器的SSL证书。打印的有关证书的信息量取决于详细程度。”

样本输出:

Starting Nmap 7.40 ( https://nmap.org ) at 2017-11-01 13:35 PDT
Nmap scan report for gnupg.org (217.69.76.60)
Host is up (0.16s latency).
Other addresses for gnupg.org (not scanned): (null)
rDNS record for 217.69.76.60: www.gnupg.org
PORT    STATE SERVICE
443/tcp open  https
| ssl-cert: Subject: commonName=gnupg.org
| Subject Alternative Name: DNS:gnupg.org, DNS:www.gnupg.org
| Issuer: commonName=Gandi Standard SSL CA 2/organizationName=Gandi/stateOrProvinceName=Paris/countryName=FR
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2015-12-21T00:00:00
| Not valid after:  2018-03-19T23:59:59
| MD5:   c3a7 e0ed 388f 87cb ec7f fd3e 71f2 1c3e
|_SHA-1: 5196 ecf5 7aed 139f a511 735b bfb5 7534 df63 41ba

Nmap done: 1 IP address (1 host up) scanned in 2.31 seconds

15
2017-11-01 20:37





要检查SSL证书详细信息,我使用以下命令行工具,因为它可用:

https://github.com/azet/tls_tools

很好地仔细检查您是否有正确的重新颁发证书或验证现有证书的信息,以及少数依赖项  它不需要设置。

这是输出的前几行看起来像:

$ ./check_certificate_chain.py gnupg.org 443

>> Certificate Chain:

 [+]*       OU=Domain Control Validated, OU=Gandi Standard SSL, CN=gnupg.org
 [+]**      C=FR, O=GANDI SAS, CN=Gandi Standard SSL CA
 [+]***     C=US, ST=UT, L=Salt Lake City, O=The USERTRUST Network, OU=http://www.usertrust.com, CN=UTN-USERFirst-Hardware

>> Certificate Information:

................................................................................
- [Subject]:        OU=Domain Control Validated, OU=Gandi Standard SSL, CN=gnupg.org
- [Issuer]:     C=FR, O=GANDI SAS, CN=Gandi Standard SSL CA
- [Valid from]:     Mar 18 00:00:00 2014 GMT
- [Valid until]:    Mar 18 23:59:59 2016 GMT
- [Authority]:      Is not a CA
- [Version]:        2
- [Serial No.]:     43845251655098616578492338727643475746
- [X.509 Extension Details]:
  -- [x509_authorityKeyIdentifier]:
       keyid:B6:A8:FF:A2:A8:2F:D0:A6:CD:4B:B1:68:F3:E7:50:10:31:A7:79:21 

该输出后面是整个证书链,具有相同的详细程度。

我喜欢它而不是像openssl的s_client那样的以ssl为中心的cli工具,这个人试图完成我们大部分时间都需要的工作。当然openssl更灵活(即还检查clientcerts,奇数端口上的imaps等) - 但我并不总是需要它。

或者,如果您有时间挖掘和设置或欣赏更多功能,那么有一个更大的工具名为sslyze(因为依赖和安装不使用它)


5
2018-01-24 01:34





我为此使用了一个shell脚本。它只是openssl命令的一个包装器,它使我免于记住语法。

它提供了解析我通常感兴趣的大多数证书信息的选项,或显示原始openssl输出。

可以查询本地证书文件,也可以查询远程服务器。

用法:

$ ssl-cert-info --help
Usage: ssl-cert-info [options]

This shell script is a simple wrapper around the openssl binary. It uses
s_client to get certificate information from remote hosts, or x509 for local
certificate files. It can parse out some of the openssl output or just dump all
of it as text.

Options:

  --all-info   Print all output, including boring things like Modulus and 
               Exponent.

  --alt        Print Subject Alternative Names. These will be typically be 
               additional hostnames that the certificate is valid for.

  --cn         Print commonName from Subject. This is typically the host for 
               which the certificate was issued.

  --debug      Print additional info that might be helpful when debugging this
               script.

  --end        Print certificate expiration date. For additional functionality
               related to certificate expiration, take a look at this script:
               "http://prefetch.net/code/ssl-cert-check".

  --dates      Print start and end dates of when the certificate is valid.

  --file       Use a local certificate file for input.

  --help       Print this help message.

  --host       Fetch the certificate from this remote host.

  --issuer     Print the certificate issuer.

  --most-info  Print almost everything. Skip boring things like Modulus and
               Exponent.

  --option     Pass any openssl option through to openssl to get its raw
               output.

  --port       Use this port when conneting to remote host. If ommitted, port
               defaults to 443.

  --subject    Print the certificate Subject -- typically address and org name.

Examples:

  1. Print a list of all hostnames that the certificate used by amazon.com 
     is valid for.

     ssl-cert-info --host amazon.com --alt
     DNS:uedata.amazon.com
     DNS:amazon.com
     DNS:amzn.com
     DNS:www.amzn.com
     DNS:www.amazon.com

  2. Print issuer of certificate used by smtp.gmail.com. Fetch certficate info
     over port 465.

     ssl-cert-info --host smtp.gmail.com --port 465 --issuer
     issuer= 
         countryName               = US
         organizationName          = Google Inc
         commonName                = Google Internet Authority G2

  3. Print valid dates for the certificate, using a local file as the source of 
     certificate data. Dates are formatted using the date command and display
     time in your local timezone instead of GMT.

     ssl-cert-info --file /path/to/file.crt --dates
     valid from: 2014-02-04 16:00:00 PST
     valid till: 2017-02-04 15:59:59 PST


  4. Print certificate serial number. This script doesn't have a special option
     to parse out the serial number, so will use the generic --option flag to
     pass '-serial' through to openssl.

     ssl-cert-info --host gmail.com --option -serial
     serial=4BF004B4DDC9C2F8

你可以在这里获得脚本: http://giantdorks.org/alain/shell-script-to-check-ssl-certificate-info-like-expiration-date-and-subject/


3
2017-09-08 19:37



链接已经死了。 - Adam Matan


如果要在Windows中执行此操作,可以使用PowerShell并使用以下功能:

function Retrieve-ServerCertFromSocket ($hostname, $port=443, $SNIHeader, [switch]$FailWithoutTrust)
{
    if (!$SNIHeader) {
        $SNIHeader = $hostname
    }

    $cert = $null
    try {
        $tcpclient = new-object System.Net.Sockets.tcpclient
        $tcpclient.Connect($hostname,$port)

        #Authenticate with SSL
        if (!$FailWithoutTrust) {
            $sslstream = new-object System.Net.Security.SslStream -ArgumentList $tcpclient.GetStream(),$false, {$true}
        } else {
            $sslstream = new-object System.Net.Security.SslStream -ArgumentList $tcpclient.GetStream(),$false
        }

        $sslstream.AuthenticateAsClient($SNIHeader)
        $cert =  [System.Security.Cryptography.X509Certificates.X509Certificate2]($sslstream.remotecertificate)

     } catch {
        throw "Failed to retrieve remote certificate from $hostname`:$port because $_"
     } finally {
        #cleanup
        if ($sslStream) {$sslstream.close()}
        if ($tcpclient) {$tcpclient.close()}        
     }    
    return $cert
}

这可以让你做一些整洁的事情

#Save to file and open 
Retrieve-ServerCertFromSocket www.wrish.com 443 | Export-Certificate -FilePath C:\temp\test.cer ; start c:\temp\test.cer

#Display the cert details
Retrieve-ServerCertFromSocket www.wrish.com 443 | fl subject,*not*,Thumb*,ser*

3
2017-12-14 16:06





为了完整性:如果您已在系统上安装 Java 7或更高版本

 keytool -printcert -sslserver $host[:$port]

显示了  (尽管如此)几乎所有的细节都以一种非常丑陋的形式出现。

无论你 应该 你的系统上安装了Java我没有回答。


1
2017-09-19 20:27





nmap -sV -sC google.com -p 443

0
2017-07-27 15:58



这需要更多解释。 - Sven♦
同意需要解释,但它对我有用,所以+1 - Jeff


如果您只想要到期日(这不是答案,而是人们使用Chrome证书详细信息的9/10),您可以使用:

echo | openssl s_client -connect google.com:443 2>/dev/null | openssl x509 -noout -enddate

对脚本等有用

c4urself@eos ~ → which ssl_expiry
ssl_expiry () {
  echo | openssl s_client -connect ${1}:443 2> /dev/null | openssl x509 -noout -enddate
}
c4urself@eos ~ → ssl_expiry google.com
notAfter=Jun 12 16:54:00 2018 GMT

0
2018-04-06 02:17