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


187

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

在此处输入图片说明

当我尝试使用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或其他)获取完整的证书信息吗?



可能也取决于版本。我当前的curl带有标志--verbose显示完整的服务器证书内容。
帕特里克·梅夫克

Answers:


263

您应该可以出于自己的目的使用OpenSSL:

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

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

(请注意,“冗余” -servername参数对于openssl在SNI支持下发出请求是必需的。)


该命令似乎有一个错误:OpenSSL> openssl:Error: 'CONNECTED(00000003)' is an invalid command.
Adam Matan 2015年

2
@AdamMatan在第二个管道之后添加了完整命令吗?错误消息看起来像第二个opensl调用最终以交互模式(即opensslvs openssl x509 -inform pem -noout -text)运行。佩德罗写的东西对我来说很好。
哈坎·林奎斯特

4
请注意,尽管s_client将打印整个链,但最后一个管道命令将仅打印有关第一个证书的信息。
chutz '16

1
echo它本身等效于echo ''..它向stdout发送一个空字符串。cat /dev/null |也会工作,并且更不言自明。

2
如果您只想知道到期日期,可以将替换-text-enddate,检查其他选项(openssl x509 help)。
adriaan

63

简单的解决方案

那是我的日常脚本:

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

5
对我不起作用,不包括开始/到期日期。
Per Lundberg

4
由于最近卷曲度发生了一些变化(介于49和52之间),因此根本不显示有关证书的任何信息。:(
Ross Presser

删除2>&1
Jeshan Babooa

27

取决于您想要哪种信息,但是:

openssl s_client -showcerts -connect gnupg.org:443

应该可以给您带来最大的收益,尽管它不像Chrome所展示的那样可读。


1
不幸的是,该命令很少以人类可读的格式显示证书数据。
哈坎·林奎斯特

9
我不同意先前的评论,该命令告诉我我需要知道的内容,并且非常有用。+1以作答。
camdixon

如果您特别想测试TLS 1.2,则可以添加-tls1_2
camdixon,

23
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

6

为了检查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 

在输出之后,将以相同的详细程度跟随整个证书链。

我喜欢这样的东西,而不是像opensl的​​s_client这样的以ssl为中心的cli工具,它试图只完成我们大多数时间需要的一项工作。当然,openssl更灵活(即也检查客户端证书,奇数端口上的imaps等)-但是我并不总是需要它。

另外,如果您有时间研究和设置或欣赏更多功能,则可以使用名为sslyze的较大工具(由于依赖和安装,因此不予使用...)


5

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

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

以几乎相当丑陋的格式显示了(已送达)的几乎所有细节。

我是否回答您是否应该在系统上安装Java。


精巧,比openssl(需要解码)有用的默认输出。
西蒙

4

我为此使用一个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/


链接已死。
亚当·马坦

4

如果要在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*


2

如果您只希望失效日期(这不是确切答案,而是人们使用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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.