如何从网站下载SSL证书?


Answers:


246

为了下载证书,您需要使用openssl内置的客户端,如下所示:

echo -n | openssl s_client -connect HOST:PORTNUMBER \
    | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > /tmp/$SERVERNAME.cert

这会将证书保存到/tmp/$SERVERNAME.cert

-showcerts如果要下载链中的所有证书,可以使用。但是,如果您只想下载服务器证书,则无需指定-showcerts

echo -n 给服务器一个响应,以便释放连接

sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p'删除有关证书链和连接详细信息的信息。这是将证书导入其他密钥库的首选格式。


9
感谢您不仅给出了很好的答案,而且给出了准确的解释。
marco.m 2014年

是否也-showcerts显示服务器/叶子证书?我以为只在包含该开关时才显示中间物。
Mike B

如答案s_client所示,始终显示服务器证书(如果有证书,即服务器响应问候,并且不选择匿名套件)。-showcerts显示所有收到的证书,首先显示服务器证书,然后显示中间件和/或根。
dave_thompson_085

4
但是,这在代理的情况下不起作用。
Frederick Nord 2015年

2
这对于使用SNI(单个IP地址上的多个证书/域)的服务器也不起作用。为避免出现问题,请指定openssl的servername参数:openssl s_client -connect HOST:PORTNUMBER -servername CN
版本

60

我找到了答案。Openssl提供了它。

openssl s_client -connect $ {REMHOST}:$ {REMPORT}


2
openssl x509 -text <<EOF cert-text EOF请参阅证书的详细信息
mpapis'Aug

2
sudo rm -f cert.pem && sudo echo -n | openssl s_client -connect localhost:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > ./cert.pemserverfault.com/questions/139728/…
pulkitsinghal 2013年

这样就完成了相同操作,并跳过了sedhack。
ph

这只是检查一个证书,如果服务是负载平衡的服务器组的一部分,该服务器中的每个服务器都有不同的证书,并且可能由不同的根CA签名,该怎么办?换句话说,mitm攻击可能会使此请求通过真实的站点,然后将其他请求定向到其服务器。有什么方法可以检查吗?并获得域真正拥有的所有证书的列表?
Jens Timmerman 2014年

@JensTimmerman “或者换句话说,通过mitm攻击可能使此请求通过真实站点,然后将其他请求定向到他的服务器。” 除非中间人拥有目标服务器的有效证书(否则客户端很傻,不检查服务器证书),否则这是不可能的。显然,如果服务器有时提供不同的证书,则您只能希望通过重复连接尝试最终获得所有证书。
David Tonhofer 2015年

22

GNUTLS客户端工具,gnutls-cli也可以使这个简单的:

gnutls-cli --print-cert www.example.com \
        < /dev/null \
        > www.example.com.certs

该程序旨在为站点提供交互式客户端,因此您需要向其提供空输入(在本示例中为from /dev/null)以结束交互式会话。


1
它如何使gnutls通过(在系统范围内配置的)https代理连接并打印其交换的证书?
Frederick Nord

9

基于@bignose答案,这是一个自包含的版本,非常适合例如厨师食谱:

sudo apt-get install gnutls-bin 
gnutls-cli --print-cert myserver.com </dev/null| sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > myserver.crt
sudo cp myserver.crt /usr/local/share/ca-certificates/myserver.crt
sudo update-ca-certificates

6
true | openssl s_client -connect google.com:443 2>/dev/null | openssl x509

openssl的这种模式需要stdin,因此我们通过提供它true |,它连接到-connect参数中指定的服务器。2>/dev/null使错误静音(可选),我们可以将整个输出传递到x509解析器中,指定/dev/stdin使用shell管道作为输入文件。它将仅输出输出的-----BEGIN CERTIFICATE-----to -----END CERTIFICATE-----部分s_client。您可以通过添加> google.com.pem到命令末尾来将其重定向到文件。


尽我所知,这不会验证证书链,只能告诉您最终服务器提供的SSL身份。


2
(1)并不能真正改善6年前的答案(2)x509默认情况下读取标准输入,因此-in /dev/stdin是多余的(3)s_client验证服务器证书已正确链接到本地​​信任锚(根)并且未过期,但是您已经禁止显示此信息的信息(4)它不检查吊销(5)它仅在1.0.2中检查服务器证书中的名称,然后默认情况下不检查(但是您可以通过查看证书轻松地检查自己)之后)
dave_thompson_085 '16

@ dave_thompson_085,问题是如何下载证书,但不显示链信息。我喜欢openssl x509比其他答案中的sed好得多。
Der_Meister

0

使用Ex和流程替换的替代语法:

ex +'/BEGIN CERTIFICATE/,/END CERTIFICATE/p' <(echo | openssl s_client -showcerts -connect example.com:443) -scq > file.crt
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.