Spring Boot调用Rest API报readHandshakeRecord SSL异常如何解决
SSL握手报错readHandshakeRecord 解决方案
1 先修复现有代码的明显错误
- 你的自定义跳过证书方法只定义了HostnameVerifier,没有设置到全局生效,需要补充代码:
// 在定义完hv变量之后新增这一行 HttpsURLConnection.setDefaultHostnameVerifier(hv);
- 你配置keystore的系统属性名拼写错误,
javax.net.ssl.keystore要修改为正确大小写格式javax.net.ssl.keyStore,JVM系统属性对大小写敏感,拼写错误会导致配置完全不生效。 - 你创建SSLContext用的协议是
SSL,现在绝大多数服务端都已经禁用了不安全的SSL协议,修改为TLSv1.2或者TLSv1.3适配最新的服务端要求:
SSLContext sc = SSLContext.getInstance("TLSv1.2");
2 确认HTTP客户端适配跳过逻辑
你写的跳过证书方法只对JDK自带的HttpsURLConnection生效,如果你在Spring Boot中用的是RestTemplate、WebClient,且底层用的是Apache HttpClient、OkHttp等第三方HTTP客户端,上述配置完全不会生效,需要针对你使用的HTTP客户端单独配置跳过证书的SSL上下文。
比如针对RestTemplate使用HttpClient的配置示例:
// 配置支持跳过证书的HttpClient SSLContext sslContext = SSLContexts.custom() .loadTrustMaterial((chain, authType) -> true) .build(); SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext, (hostname, session) -> true); CloseableHttpClient httpClient = HttpClients.custom() .setSSLSocketFactory(csf) .build(); // 用自定义的httpClient构造RestTemplate RestTemplate restTemplate = new RestTemplate(new HttpComponentsClientHttpRequestFactory(httpClient));
3 排查证书路径问题
你用的相对路径support/xxx.jks依赖应用启动时的工作目录,很容易出现找不到证书文件的问题,建议:
- 把证书文件放到项目
resources目录下,通过类路径读取转成绝对路径再赋值给系统属性 - 或者直接使用绝对路径配置,避免路径解析错误
4 避免配置冲突
如果你已经用了跳过所有证书校验的逻辑,就不需要再配置javax.net.ssl.trustStore和javax.net.ssl.keyStore相关的系统属性,二者会出现冲突,保留其中一种配置即可:
- 生产环境建议删除跳过证书的逻辑,正确配置可信证书库,保证通信安全
- 测试环境如果要跳过校验,直接删除所有javax.net.ssl相关的系统属性配置即可
5 开启SSL调试日志定位具体问题
如果上述修改都无效,可以在启动参数中添加SSL调试参数,打印详细的握手日志定位具体原因:
-Djavax.net.debug=ssl,handshake
日志中会明确输出握手失败的具体原因,比如协议不匹配、证书不被信任、域名校验失败等。
内容的提问来源于stack exchange,提问作者stikkoo
相关产品推荐
相关产品推荐

