使用openssl从服务器获取证书

时间:2022-09-15 13:11:58

I am trying to get the certificate of a remote server, which I can then use to add to my keystore and use within my java application.

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

A senior dev (who is on holidays :( ) informed me I can run this:

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

openssl s_client -connect host.host:9999

To get a raw certificate dumped out, which I can then copy and export. I receive the following output:

为了得到一个原始证书,我可以将其复制并导出。我收到如下输出:

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:

I have also tried with this option

我也尝试过这个选项

-showcerts 

and this one (running on debian mind you)

这个(在debian上运行)

-CApath /etc/ssl/certs/ 

But get the same error.

但是得到同样的错误。

This source says I can use that CApath flag but it doesn't seem to help. I tried multiple paths to no avail.

这个消息来源说我可以使用卡帕特旗帜,但似乎没有帮助。我尝试了多种路径,但没有成功。

Please let me know where I'm going wrong.

请告诉我哪里出错了。

9 个解决方案

#1


294  

With SNI

If the remote server is using SNI (that is, sharing multiple SSL hosts on a single IP address) you will need to send the correct hostname in order to get the right certificate.

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

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

Without SNI

If the remote server is not using SNI, then you can skip -servername parameter:

如果远程服务器不使用SNI,则可以跳过-servername参数:

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


To view the full details of a site's cert you can use this chain of commands as well:

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

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

#2


51  

While I agree with Ari's answer (and upvoted it :), I needed to do an extra step to get it to work with Java on Windows (where it needed to be deployed):

虽然我同意Ari的回答(并对其进行了改进),但我还需要做额外的工作,使它能在Windows上使用Java(在需要部署的地方):

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

Before adding the openssl x509 -outform DER conversion, I was getting an error from keytool on Windows complaining about the certificate's format. Importing the .der file worked fine.

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

#3


32  

It turns out there is more complexity here: I needed to provide many more details to get this rolling. I think its something to do with the fact that its a connection that needs client authentication, and the hankshake needed more info to continue to the stage where the certificates were dumped.

事实证明,这里有更多的复杂性:我需要提供更多的细节来推动这一进程。我认为这与需要客户端身份验证的连接有关,hankshake需要更多的信息才能继续到证书被丢弃的阶段。

Here is my working command:

以下是我的工作指令:

openssl s_client -connect host:port -key our_private_key.pem -showcerts \
                 -cert our_server-signed_cert.pem

Hopefully this is a nudge in the right direction for anyone who could do with some more info.

希望这对任何想了解更多信息的人来说都是一个好的推动。

#4


26  

The easiest command line for this, which includes the PEM output to add it to the keystore, as well as a human readable output and also supports SNI, which is important if you are working with an HTTP server is:

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

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

The -servername option is to enable SNI support and the openssl x509 -text prints the certificate in human readable format.

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

#5


18  

To get the certificate of remote server you can use openssl tool and you can find it between BEGIN CERTIFICATE and END CERTIFICATE which you need to copy and paste into your certificate file (CRT).

要获得远程服务器的证书,可以使用openssl工具,并且可以在开始证书和结束证书之间找到证书,您需要将这些证书复制并粘贴到您的证书文件(CRT)中。

Here is the command demonstrating it:

以下是演示该命令的命令:

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

To return all certificates from the chain, just add g (global) like:

要从链中返回所有证书,只需添加g(全局)如下:

ex +'g/BEGIN CERTIFICATE/,/END CERTIFICATE/p' <(echo | openssl s_client -showcerts -connect example.com:443) -scq

Then you can simply import your certificate file (file.crt) into your keychain and make it trusted, so Java shouldn't complain.

然后,您可以简单地将证书文件(file.crt)导入到密钥链中并使其可信,这样Java就不会抱怨了。

On OS X you can double-click on the file or drag and drop in your Keychain Access, so it'll appear in login/Certificates. Then double-click on the imported certificated and make it Always Trust for SSL.

在OS X上,你可以双击文件或者拖拽你的密钥链访问,这样它就会出现在登录/证书中。然后双击导入的认证,使其始终信任SSL。

On CentOS 5 you can append them into /etc/pki/tls/certs/ca-bundle.crt file (and run: sudo update-ca-trust force-enable), or in CentOS 6 copy them into /etc/pki/ca-trust/source/anchors/ and run sudo update-ca-trust extract.

在CentOS 5上,您可以将它们附加到/etc/pki/tls/certs/ca- bundle.com。crt文件(并运行:sudo update-ca-trust force-enable)或CentOS 6将它们复制到/etc/pki/ca trust/source/anchors/并运行sudo update-ca-trust提取。

In Ubuntu, copy them into /usr/local/share/ca-certificates and run sudo update-ca-certificates.

在Ubuntu中,将它们复制到/usr/local/share/ca证书并运行sudo update-ca证书。

#6


4  

You can get and store the server root certificate using next bash script:

您可以使用下一个bash脚本获取并存储服务器根证书:

CERTS=$(echo -n | openssl s_client -connect $HOST_NAME:$PORT -showcerts | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p')
echo "$CERTS" | awk -v RS="-----BEGIN CERTIFICATE-----" 'NR > 1 { printf RS $0 > "'$SERVER_ROOT_CERTIFICATE'"; close("'$SERVER_ROOT_CERTIFICATE'") }'

Just overwrite required variables.

只是覆盖所需的变量。

#7


3  

HOST=gmail-pop.l.google.com
PORT=995

openssl s_client -servername $HOST -connect $HOST:$PORT < /dev/null 2>/dev/null | openssl x509 -outform pem

#8


3  

to print only the certificate chain and not the server's certificate:

只打印证书链而不是服务器证书:

# MYHOST=myhost.com
# MYPORT=443
# openssl s_client -connect ${MYHOST}:${MYPORT} -showcerts 2>/dev/null </dev/null | awk '/^.*'"${MYHOST}"'/,/-----END CERTIFICATE-----/{next;}/-----BEGIN/,/-----END CERTIFICATE-----/{print}'

to update CA trust on CentOS/RHEL 6/7 :

更新CentOS/RHEL 6/7的CA信任:

# update-ca-trust enable
# openssl s_client -connect ${MYHOST}:${MYPORT} -showcerts 2>/dev/null </dev/null | awk '/^.*'"${MYHOST}"'/,/-----END CERTIFICATE-----/{next;}/-----BEGIN/,/-----END CERTIFICATE-----/{print}' >/etc/pki/ca-trust/source/anchors/myca.cert
# update-ca-trust extract

on CentOS/RHEL 5:

CentOS / RHEL 5:

# openssl s_client -connect ${MYHOST}:${MYPORT} -showcerts 2>/dev/null </dev/null | awk '/^.*'"${MYHOST}"'/,/-----END CERTIFICATE-----/{next;}/-----BEGIN/,/-----END CERTIFICATE-----/{print}' >>/etc/pki/tls/certs/ca-bundle.crt

#9


1  

For the benefit of others like me who tried to follow the good advice here when accessing AWS CloudFront but failed, the trick is to add -servername domain.name...

对于像我这样的其他人来说,当访问AWS CloudFront时,他们试图遵循这里的好建议,但失败了,关键是添加-servername域。

Source: https://serverfault.com/a/780450/8972

来源:https://serverfault.com/a/780450/8972

#1


294  

With SNI

If the remote server is using SNI (that is, sharing multiple SSL hosts on a single IP address) you will need to send the correct hostname in order to get the right certificate.

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

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

Without SNI

If the remote server is not using SNI, then you can skip -servername parameter:

如果远程服务器不使用SNI,则可以跳过-servername参数:

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


To view the full details of a site's cert you can use this chain of commands as well:

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

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

#2


51  

While I agree with Ari's answer (and upvoted it :), I needed to do an extra step to get it to work with Java on Windows (where it needed to be deployed):

虽然我同意Ari的回答(并对其进行了改进),但我还需要做额外的工作,使它能在Windows上使用Java(在需要部署的地方):

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

Before adding the openssl x509 -outform DER conversion, I was getting an error from keytool on Windows complaining about the certificate's format. Importing the .der file worked fine.

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

#3


32  

It turns out there is more complexity here: I needed to provide many more details to get this rolling. I think its something to do with the fact that its a connection that needs client authentication, and the hankshake needed more info to continue to the stage where the certificates were dumped.

事实证明,这里有更多的复杂性:我需要提供更多的细节来推动这一进程。我认为这与需要客户端身份验证的连接有关,hankshake需要更多的信息才能继续到证书被丢弃的阶段。

Here is my working command:

以下是我的工作指令:

openssl s_client -connect host:port -key our_private_key.pem -showcerts \
                 -cert our_server-signed_cert.pem

Hopefully this is a nudge in the right direction for anyone who could do with some more info.

希望这对任何想了解更多信息的人来说都是一个好的推动。

#4


26  

The easiest command line for this, which includes the PEM output to add it to the keystore, as well as a human readable output and also supports SNI, which is important if you are working with an HTTP server is:

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

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

The -servername option is to enable SNI support and the openssl x509 -text prints the certificate in human readable format.

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

#5


18  

To get the certificate of remote server you can use openssl tool and you can find it between BEGIN CERTIFICATE and END CERTIFICATE which you need to copy and paste into your certificate file (CRT).

要获得远程服务器的证书,可以使用openssl工具,并且可以在开始证书和结束证书之间找到证书,您需要将这些证书复制并粘贴到您的证书文件(CRT)中。

Here is the command demonstrating it:

以下是演示该命令的命令:

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

To return all certificates from the chain, just add g (global) like:

要从链中返回所有证书,只需添加g(全局)如下:

ex +'g/BEGIN CERTIFICATE/,/END CERTIFICATE/p' <(echo | openssl s_client -showcerts -connect example.com:443) -scq

Then you can simply import your certificate file (file.crt) into your keychain and make it trusted, so Java shouldn't complain.

然后,您可以简单地将证书文件(file.crt)导入到密钥链中并使其可信,这样Java就不会抱怨了。

On OS X you can double-click on the file or drag and drop in your Keychain Access, so it'll appear in login/Certificates. Then double-click on the imported certificated and make it Always Trust for SSL.

在OS X上,你可以双击文件或者拖拽你的密钥链访问,这样它就会出现在登录/证书中。然后双击导入的认证,使其始终信任SSL。

On CentOS 5 you can append them into /etc/pki/tls/certs/ca-bundle.crt file (and run: sudo update-ca-trust force-enable), or in CentOS 6 copy them into /etc/pki/ca-trust/source/anchors/ and run sudo update-ca-trust extract.

在CentOS 5上,您可以将它们附加到/etc/pki/tls/certs/ca- bundle.com。crt文件(并运行:sudo update-ca-trust force-enable)或CentOS 6将它们复制到/etc/pki/ca trust/source/anchors/并运行sudo update-ca-trust提取。

In Ubuntu, copy them into /usr/local/share/ca-certificates and run sudo update-ca-certificates.

在Ubuntu中,将它们复制到/usr/local/share/ca证书并运行sudo update-ca证书。

#6


4  

You can get and store the server root certificate using next bash script:

您可以使用下一个bash脚本获取并存储服务器根证书:

CERTS=$(echo -n | openssl s_client -connect $HOST_NAME:$PORT -showcerts | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p')
echo "$CERTS" | awk -v RS="-----BEGIN CERTIFICATE-----" 'NR > 1 { printf RS $0 > "'$SERVER_ROOT_CERTIFICATE'"; close("'$SERVER_ROOT_CERTIFICATE'") }'

Just overwrite required variables.

只是覆盖所需的变量。

#7


3  

HOST=gmail-pop.l.google.com
PORT=995

openssl s_client -servername $HOST -connect $HOST:$PORT < /dev/null 2>/dev/null | openssl x509 -outform pem

#8


3  

to print only the certificate chain and not the server's certificate:

只打印证书链而不是服务器证书:

# MYHOST=myhost.com
# MYPORT=443
# openssl s_client -connect ${MYHOST}:${MYPORT} -showcerts 2>/dev/null </dev/null | awk '/^.*'"${MYHOST}"'/,/-----END CERTIFICATE-----/{next;}/-----BEGIN/,/-----END CERTIFICATE-----/{print}'

to update CA trust on CentOS/RHEL 6/7 :

更新CentOS/RHEL 6/7的CA信任:

# update-ca-trust enable
# openssl s_client -connect ${MYHOST}:${MYPORT} -showcerts 2>/dev/null </dev/null | awk '/^.*'"${MYHOST}"'/,/-----END CERTIFICATE-----/{next;}/-----BEGIN/,/-----END CERTIFICATE-----/{print}' >/etc/pki/ca-trust/source/anchors/myca.cert
# update-ca-trust extract

on CentOS/RHEL 5:

CentOS / RHEL 5:

# openssl s_client -connect ${MYHOST}:${MYPORT} -showcerts 2>/dev/null </dev/null | awk '/^.*'"${MYHOST}"'/,/-----END CERTIFICATE-----/{next;}/-----BEGIN/,/-----END CERTIFICATE-----/{print}' >>/etc/pki/tls/certs/ca-bundle.crt

#9


1  

For the benefit of others like me who tried to follow the good advice here when accessing AWS CloudFront but failed, the trick is to add -servername domain.name...

对于像我这样的其他人来说,当访问AWS CloudFront时,他们试图遵循这里的好建议,但失败了,关键是添加-servername域。

Source: https://serverfault.com/a/780450/8972

来源:https://serverfault.com/a/780450/8972