Openssl
可以使用 openssl 命令来查看 SSL/TLS 证书中包含的域名信息。具体命令如下:
openssl x509 -noout -text -in [证书文件名]
运行这个命令后,会在输出中看到「Subject Alternative Name」字段,这个字段里包含了证书支持的所有域名。 也可以使用 openssl s_client -connect 命令来验证证书的域名信息
openssl s_client -connect [域名]:443
连接成功的话会输出域名相关证书信息,此处也可以看到 Subject Alternative Name.
Java
-Djavax.net.debug=ssl
https://docs.oracle.com/javase/7/docs/technotes/guides/security/jsse/ReadDebug.html
ssl 异常
Server’s Certificate is Not Available
当启动服务端组件时,你会在日志中看到如下的异常:
javax.net.ssl.SSLException: No available certificate or key corresponds to the SSL cipher suites which are enabled
大部分情况下表示你没有配置包含服务端密钥的 keystore 以及相应的证书。
解决办法
使用 keystore 系统属性 或者服务端组件 ssl 属性中的 keyStore 属性。你必须指定包含服务端密钥以及证书的 keystore 的路径以及密码。
Client Does Not Trust the Server
当客户端尝试连接服务端时,在日志中看到如下的异常:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed
这个问题表示服务端展示的证书,客户端不相信。大部分情况下是使用自签名的证书 (或者服务端证书由你组织内部的认证机构所签名) 并且你还没有配置客户端,导致它引用了包含服务端自签名证书 (或者你的服务器证书是由 CA 签名的受信任的根证书) 的 truststore。
这个问题还会发生在服务端证书过期或者被取消的情况下。在客户端每次尝试进行连接时,你在服务端的日志中会看到如下的异常信息:
javax.net.ssl.SSLHandshakeException: Received fatal alert: …
异常信息的余下部分通常会提供一个代码来表明为什么客户端拒绝服务端证书:
代码 描述
certificate_unknown 通常表示客户端 truststore 没有被正确的配置
certificate_expired 表示服务端证书已过期,需要更换
certificate_revoked 表示颁发的 CA 已经撤销了服务端证书,需要更换
解决办法
如果服务端日志显示 certificate_unknown,那么使用 truststore 系统属性 或者 appender 组件 ssl 属性中的 trustStore 属性,指定包含服务端自签名证书或者颁发的 CA 根证书的 truststore 的路径以及密码。
如果服务端日志显示 certificate_expired 或者 certificate_revoked,表示服务端需要一个新的证书。新的证书以及相关的密钥需要在服务端配置的 keystore 中更换。并且,如果使用自签名服务端证书,那么还需要更换在客户端 appender 中配置的 truststore 服务端证书。
Server Does Not Trust the Client
注意:这个问题仅仅发生在你明确的配置服务端请求客户端证书时。(使用 needClientAuth 或者 wantClientAuth 属性)。
当客户端尝试连接日志服务器时,可以在客户端日志中看到如下的异常信息:
javax.net.ssl.SSLHandshakeException: Received fatal alert: …
异常信息的其余部分会提供一个代码表明为什么服务端拒绝客户端证书。
代码 描述
certificate_unknown 通常表示服务端 truststore 没有正确的配置
certificate_expired 表示客户端证书已经过期,需要更换
certificate_revoked 表示颁发的 CA 已经撤销了客户端证书,需要更换
解决办法
如果客户端日志信息显示 bad_certificate,那么使用 truststore 系统属性 或者服务端组件 ssl 属性中的 trustStore 属性,指定包含客户端自签名证书或者颁发的 CA 根证书的 truststore 的路径以及密码。
如果服务端日志信息显示 certificate_expired 或者 certificate_revoked,表示客户端需要一个新的证书。需要更换在客户端配置中指定的 keystore 的新证书以及相应的密钥。
Client and Server Cannot Agree on a Protocol
注意:这个问题仅仅只在你的配置中明确的配置了 excludedProtocols 或者 includedProtocols SSL 协议时。
当客户端尝试连接服务端时,你会在日志中看到如下异常信息:
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
服务端的日志信息通常更加详细,例如:
javax.net.ssl.SSLHandshakeException: SSLv2Hello is disabled
通常,表示你已经排除其中的一个协议。
解决办法
检查服务端与客户端指定的 excludedProtocols 以及 includedProtocols 属性的值。
Client and Server Cannot Agree on a Cipher Suite
注意:通常这个问题只发生在你明确的在配置文件中指定了 excludedCipherSuites 或者 includedCipherSuites SSL 密码套件时。
当客户端尝试去连接服务端时,你会在日志中看到如下的异常信息:
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
服务端的日志信息通常会更加详细:
javax.net.ssl.SSLHandshakeException: no cipher suites in common
``
这意味着你已经在服务端与客户端配置了密码套件,但是它们各自密码套件的交集为空。
解决办法
检查服务端与客户端指定的 excludedCipherSuites 以及 includedCipherSuites 属性的值。