为何该Java代码场景中HostnameVerifier会返回false?
HostnameVerifier验证返回false的原因及修复
你的代码返回false的核心原因是SSLSocket仅建立了TCP连接,但未完成SSL握手,导致getSession()获取的是未初始化的SSL会话,里面没有服务器证书信息,默认HostnameVerifier无法完成域名校验。
具体细节
SSLSocketFactory.createSocket(host, port)只会完成底层TCP连接的建立,并不会自动触发SSL握手流程。此时SSL会话处于未初始化状态,没有服务器的证书链数据。- 默认的
DefaultHostnameVerifier校验逻辑依赖SSL会话中的服务器证书:它会提取证书中的域名(CN字段或SAN扩展),与传入的host参数比对。如果会话没有证书数据,校验直接失败,返回false。
修复代码
只需要在获取会话前主动触发SSL握手即可:
public static void main(String[] argv) throws UnknownHostException, IOException { String host = "stackoverflow.com"; Integer port = 443; SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault(); SSLSocket socket = (SSLSocket) factory.createSocket(host, port); // 主动触发SSL握手,完成会话初始化 socket.startHandshake(); if (socket.isConnected()) { boolean valid = HttpsURLConnection.getDefaultHostnameVerifier().verify(host, socket.getSession()); System.out.println("valid is " + valid); socket.close(); } }
执行修正后的代码,valid会返回true,因为此时SSL会话已经完成握手,包含了stackoverflow.com的合法证书,域名校验可以正常完成。
内容的提问来源于stack exchange,提问作者gogators
相关产品推荐
相关产品推荐

