我正在尝试获得远程服务器的证书,然后可以将其添加到我的密钥存储库中并在Java应用程序中使用。

一位高级开发人员(他正在度假:)告诉我,我可以运行这个:

openssl s_client -connect host.host:9999

来获得一个原始证书,然后我可以复制和导出。我收到以下输出:

depth=1 /C=NZ/ST=Test State or Province/O=Organization Name/OU=Organizational Unit Name/CN=Test CA
verify error:num=19:self signed certificate in certificate chain
verify return:0
23177:error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure:s3_pkt.c:1086:SSL alert number 40
23177:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:s23_lib.c:188:

我也尝试过这个选项:

-showcerts

还有这个(在Debian上运行):

-CApath /etc/ssl/certs/

但是我得到了同样的错误。

这个消息来源说我可以使用CApath标志,但它似乎没有帮助。我尝试了多种途径,但都无济于事。

请告诉我哪里做错了。


当前回答

与SNI

如果远程服务器使用SNI(即在一个IP地址上共享多个SSL主机),则需要发送正确的主机名以获得正确的证书。

openssl s_client -showcerts -servername www.example.com -connect www.example.com:443 </dev/null

没有SNI

如果远程服务器没有使用SNI,那么你可以跳过-servername parameter:

openssl s_client -showcerts -connect www.example.com:443 </dev/null

要查看站点证书的完整细节,您也可以使用以下命令链:

$ echo | \
    openssl s_client -servername www.example.com -connect www.example.com:443 2>/dev/null | \
    openssl x509 -text

其他回答

最简单的命令行包括PEM输出,将其添加到密钥库中,以及人类可读的输出,还支持SNI,如果您使用HTTP服务器,这很重要:

openssl s_client -servername example.com -connect example.com:443 \
    </dev/null 2>/dev/null | openssl x509 -text

-servername选项用于启用SNI支持,openssl x509 -text以人类可读的格式打印证书。

虽然我同意Ari的回答(并为其点赞:),但我需要做额外的步骤来让它在Windows上与Java一起工作(需要在Windows上部署):

openssl s_client -showcerts -connect www.example.com:443 < /dev/null | openssl x509 -outform DER > derp.der

在添加openssl x509 -outform DER转换之前,我从Windows上的keytool得到一个错误,抱怨证书的格式。导入.der文件工作正常。

我是在这种情况下,从上述命令输出两个证书;所以现在我只提取了第二部分:服务器证书

对不起,命令太长了:

openssl s_client -servername token.actions.githubusercontent.com -showcerts -connect token.actions.githubusercontent.com:443 2>/dev/null </dev/null | awk '/BEGIN CERTIFICATE/ && c++,/END CERTIFICATE/' 

已经有了很好的答案。但是值得一提的是,最新的curl版本(>7.88.0)将为您简单地完成此操作…

curl https://example.com -w "%{certs}" -o /dev/null > cacert.pem

如果服务器使用自签名证书,则添加——insecure。并添加——head以避免响应体。

查看可用性和要求: cURL -w certs特性

我也有同样的挑战,然后我发现openssl不返回根ca。我已经专门为此目的构建了一个替代方案,这可能对其他开发人员有用,参见这里:GitHub -证书开锁器

使用

打印到控制台

crip print --url=https://stackoverflow.com/ --format=pem

导出到p12信任库

crip export pkcs12 --url=https://stackoverflow.com/

如果需要不同的输出,可以将pkcs12选项替换为pem或der。