“握手失败”表示握手失败,并且没有SSL / TLS连接。您应该看到openssl
退出到外壳程序(或CMD等),并且不等待输入数据发送到服务器。“验证返回码0”表示在服务器的证书中未发现任何问题,或者是因为它根本没有被检查过,或者因为它已经过检查并且质量很好(就OpenSSL的检查而言,这并不涵盖所有内容);在这种情况下,通过了解协议,我们可以推断出后一种情况适用。
接收警报bad certificate
(代码42)意味着服务器要求您使用证书进行身份验证,但您没有这样做,这导致了握手失败。行前几行SSL handshake has read ... and written ...
,你会看到一条线Acceptable client certificate CA names
通常由几个线路识别的CA,可能跟着一行开始Client Certificate Types
,也许一些关于Requested Signature Algorithms
具体取决于您的OpenSSL版本,协商的协议。
在“可接受”列表中找到由CA颁发的证书,或者如果该证书为空,请在服务器上或有关服务器的文件中查找其信任的CA或与服务器运营商或所有者联系并询问他们,以及相匹配的私钥,两者以PEM格式,并使用-cert $file -key $file
;如果两者都在一个文件中(如PEM一样),则只需使用-cert $file
。如果您使用其他格式,则可以指定它,或者在此处搜索,也可以在超级用户和安全性中搜索。关于转换各种证书和私钥格式的问题已经很多。如果您的证书需要验证“链式”或“中间”证书(甚至多个),那么根据服务器的配置,通常是来自公共CA(相对于内部CA)的证书,s_client
需要技巧:将链证书添加到您的系统信任库中,或创建一个本地/临时信任库,其中包含需要验证服务器的CA证书以及需要发送的链证书。
如果您没有这样的证书,则需要获得一个证书,这是另一个问题,需要更多详细信息来回答,或者您需要找到一种无需使用证书身份验证即可连接到服务器的方法。再次检查文档和/或询问操作员/所有者。
编辑:从注释中看来,您可能具有Java中的客户端密钥和证书链以及服务器锚。在检查时,我看不到一个很好的现有答案可以完全解决该问题,因此即使搜索效果可能不太好:
# Assume Java keystore is type JKS (the default but not only possibility)
# named key.jks and the privatekey entry is named mykey (ditto)
# and the verify certs are in trust.jks in entries named trust1 trust2 etc.
# convert Java key entry to PKCS12 then PKCS12 to PEM files
keytool -importkeystore -srckeystore key.jks -destkeystore key.p12 -deststoretype pkcs12 -srcalias mykey
openssl pkcs12 -in key.p12 -nocerts -out key.pem
openssl pkcs12 -in key.p12 -nokeys -clcerts -out cert.pem
openssl pkcs12 -in key.p12 -nokeys -cacerts -out chain.pem
# extract verify certs to individual PEM files
# (or if you 'uploaded' PEM files and still have them just use those)
keytool -keystore trust.jks -export -alias trust1 -rfc -file trust1.pem
keytool -keystore trust.jks -export -alias trust2 -rfc -file trust2.pem
... more if needed ...
# combine for s_client
cat chain.pem trust*.pem >combined.pem
openssl s_client -connect host:port -key key.pem -cert cert.pem -CAfile combined.pem