news 2026/6/10 19:08:10

解决Java中IP地址访问HTTPS接口的SSL证书验证问题

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
解决Java中IP地址访问HTTPS接口的SSL证书验证问题

问题描述

在使用Java的RestTemplate访问HTTPS接口时,如果使用IP地址而不是域名,经常会遇到以下错误:

java.security.cert.CertificateException: No subject alternative names matching IP address 111.63.81.79 found nested exception is javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative names matching IP address 111.63.81.79 found

奇怪的是:使用Postman、curl等工具可以正常访问,但Java代码却报错。

问题原因

SSL证书验证机制

HTTPS协议在建立连接时,会进行SSL证书验证,主要包括两个方面:

  1. 证书有效性验证:检查证书是否过期、是否被吊销等
  2. 主机名验证:检查证书中的域名或IP地址是否与访问的地址匹配

为什么Postman可以,Java不行?

  • Postman:默认情况下,Postman可能会跳过某些SSL验证(特别是开发环境)
  • Java:Java的SSL验证非常严格,会检查证书的Subject Alternative Names (SAN)字段
  • 问题根源:当使用IP地址访问时,如果证书的SAN中没有包含该IP地址,Java就会拒绝连接

证书的Subject Alternative Names

SSL证书中有一个字段叫Subject Alternative Names (SAN),它列出了该证书可以用于哪些域名或IP地址。例如:

Subject Alternative Names: DNS: example.com DNS: www.example.com IP Address: 192.168.1.1

如果证书中没有包含你访问的IP地址(如111.63.81.79),Java就会抛出上述异常。

解决方案

方案概述

我们需要配置RestTemplate,让它跳过SSL证书验证。注意:这种方法只适用于开发/测试环境,生产环境应该使用正确的证书。

完整代码实现

创建一个RestTemplateConfig配置类:

packagecom.example.zbx.config;importorg.apache.http.client.config.RequestConfig;importorg.apache.http.conn.ssl.NoopHostnameVerifier;importorg.apache.http.conn.ssl.SSLConnectionSocketFactory;importorg.apache.http.impl.client.CloseableHttpClient;importorg.apache.http.impl.client.HttpClients;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.http.client.HttpComponentsClientHttpRequestFactory;importorg.springframework.web.client.RestTemplate;importjavax.net.ssl.SSLContext;importjavax.net.ssl.TrustManager;importjavax.net.ssl.X509TrustManager;importjava.security.cert.X509Certificate;/** * RestTemplate配置类 * 配置忽略SSL证书验证,支持使用IP地址访问HTTPS接口 * @author lxy */@ConfigurationpublicclassRestTemplateConfig{/** * 创建RestTemplate Bean * 配置忽略SSL证书验证,支持使用IP地址访问HTTPS接口 * @return RestTemplate实例 */@BeanpublicRestTemplaterestTemplate(){try{// 创建完全信任所有证书的TrustManagerTrustManager[]trustAllCerts=newTrustManager[]{newX509TrustManager(){@OverridepublicX509Certificate[]getAcceptedIssuers(){returnnull;}@OverridepublicvoidcheckClientTrusted(X509Certificate[]certs,StringauthType){// 不进行任何检查,信任所有客户端证书}@OverridepublicvoidcheckServerTrusted(X509Certificate[]certs,StringauthType){// 不进行任何检查,信任所有服务器证书}}};// 创建SSL上下文,使用自定义的TrustManagerSSLContextsslContext=SSLContext.getInstance("TLS");sslContext.init(null,trustAllCerts,newjava.security.SecureRandom());// 创建SSL连接工厂,忽略主机名验证(包括IP地址验证)SSLConnectionSocketFactorysslSocketFactory=newSSLConnectionSocketFactory(sslContext,NoopHostnameVerifier.INSTANCE);// 创建请求配置RequestConfigrequestConfig=RequestConfig.custom().setConnectTimeout(10000)// 连接超时10秒.setConnectionRequestTimeout(10000)// 请求超时10秒.setSocketTimeout(30000)// 读取超时30秒.build();// 创建HttpClientCloseableHttpClienthttpClient=HttpClients.custom().setSSLSocketFactory(sslSocketFactory).setDefaultRequestConfig(requestConfig).evictExpiredConnections().evictIdleConnections(30,java.util.concurrent.TimeUnit.SECONDS).build();// 创建请求工厂HttpComponentsClientHttpRequestFactoryfactory=newHttpComponentsClientHttpRequestFactory();factory.setHttpClient(httpClient);factory.setConnectTimeout(10000);factory.setConnectionRequestTimeout(10000);factory.setReadTimeout(30000);// 创建RestTemplatereturnnewRestTemplate(factory);}catch(Exceptione){thrownewRuntimeException("创建RestTemplate失败",e);}}}

关键点说明

1. 自定义TrustManager
TrustManager[]trustAllCerts=newTrustManager[]{newX509TrustManager(){@OverridepublicvoidcheckServerTrusted(X509Certificate[]certs,StringauthType){// 不进行任何检查,信任所有服务器证书}// ... 其他方法}};

这个X509TrustManager会跳过所有证书验证,包括:

  • 证书是否过期
  • 证书是否被吊销
  • 证书的域名/IP是否匹配
2. 创建SSL上下文
SSLContextsslContext=SSLContext.getInstance("TLS");sslContext.init(null,trustAllCerts,newjava.security.SecureRandom());

使用自定义的TrustManager初始化SSL上下文。

3. 忽略主机名验证
SSLConnectionSocketFactorysslSocketFactory=newSSLConnectionSocketFactory(sslContext,NoopHostnameVerifier.INSTANCE// 不验证主机名);

NoopHostnameVerifier.INSTANCE会跳过主机名验证,这样即使证书中没有对应的IP地址也能通过验证。

Maven依赖

确保你的pom.xml中包含以下依赖:

<!-- HttpClient4 (for RestTemplate SSL configuration) --><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId></dependency>

使用示例

配置完成后,直接使用RestTemplate即可,无需额外代码:

@AutowiredprivateRestTemplaterestTemplate;publicvoidcallApi(){Stringurl="https://111.63.81.79:10091/api/endpoint";ResponseEntity<String>response=restTemplate.postForEntity(url,request,String.class);// 处理响应...}

注意事项

⚠️ 安全警告

  1. 仅用于开发/测试环境:跳过SSL验证会带来安全风险,生产环境不应该使用
  2. 中间人攻击风险:攻击者可以伪造证书,你的应用无法识别
  3. 数据泄露风险:无法保证连接的安全性

生产环境建议

如果必须在生产环境使用,建议:

  1. 使用正确的证书:让服务器提供包含IP地址的证书
  2. 配置证书信任:只信任特定的证书颁发机构(CA)
  3. 使用域名访问:尽量使用域名而不是IP地址

示例:生产环境的正确做法

// 只信任特定的证书KeyStoretrustStore=KeyStore.getInstance("JKS");trustStore.load(newFileInputStream("truststore.jks"),"password".toCharArray());TrustManagerFactorytrustManagerFactory=TrustManagerFactory.getInstance("X509");trustManagerFactory.init(trustStore);SSLContextsslContext=SSLContext.getInstance("TLS");sslContext.init(null,trustManagerFactory.getTrustManagers(),null);

常见问题

Q1: 为什么之前可以,现在不行了?

可能的原因:

  • Java版本更新,SSL验证更严格了
  • 服务器证书更新了,新证书没有包含IP地址
  • 网络环境变化,使用了不同的IP地址

Q2: 有没有更简单的办法?

对于开发环境,可以设置JVM参数(不推荐):

-Dcom.sun.net.ssl.checkRevocation=false

但这种方法不够灵活,建议使用配置类的方式。

Q3: 会影响其他HTTP请求吗?

不会。这个配置只影响使用RestTemplate的HTTPS请求,HTTP请求不受影响。

Q4: 如何验证配置是否生效?

在代码中添加日志,观察是否还有证书验证错误:

log.info("RestTemplate配置完成,SSL验证已禁用");

如果不再出现CertificateException,说明配置生效了。

总结

  1. 问题根源:Java的SSL验证严格,证书中没有IP地址时会拒绝连接
  2. 解决方案:配置RestTemplate跳过SSL证书验证
  3. 关键代码:自定义X509TrustManager+NoopHostnameVerifier
  4. 安全提醒:仅用于开发/测试环境,生产环境应使用正确的证书

参考资源

  • Apache HttpClient SSL配置文档
  • Java SSL/TLS编程指南
  • Spring RestTemplate文档
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/10 4:06:57

零代码基础也能玩转PSD:Python神器PSD Tools完全解析手册

零代码基础也能玩转PSD&#xff1a;Python神器PSD Tools完全解析手册 【免费下载链接】psd-tools 项目地址: https://gitcode.com/gh_mirrors/ps/psd-tools 还在为打不开PSD文件而烦恼吗&#xff1f;无需安装庞大的Photoshop软件&#xff0c;只需掌握这个强大的Python工…

作者头像 李华
网站建设 2026/6/10 12:01:32

变形监测技术的革新及北斗系统在国内应用的优势分析

本文围绕变形监测技术的革新&#xff0c;特别强调北斗系统在国内应用的优势。随着技术的迅猛发展&#xff0c;GNSS形变监测及单北斗GNSS应用逐渐成为关键领域。在基础设施安全监测方面&#xff0c;北斗形变监测传感器提供了毫米级的精准定位能力&#xff0c;确保了实时数据信息…

作者头像 李华
网站建设 2026/6/10 11:57:54

Simple Live跨平台直播聚合工具:打造高效观看新体验

面对众多直播平台分散、内容查找繁琐的困扰&#xff0c;Simple Live应运而生&#xff0c;这款基于Flutter技术栈的跨平台解决方案&#xff0c;彻底改变了传统直播观看模式。通过统一界面整合主流直播平台资源&#xff0c;为用户提供前所未有的便捷体验。 【免费下载链接】dart_…

作者头像 李华
网站建设 2026/6/9 13:48:02

9个降AI率工具推荐,专科生高效避坑指南

9个降AI率工具推荐&#xff0c;专科生高效避坑指南 AI降重工具&#xff1a;专科生论文的“隐形护盾” 在当前高校论文写作中&#xff0c;随着AI技术的广泛应用&#xff0c;越来越多的学生开始使用AI辅助写作&#xff0c;但随之而来的AIGC率高、查重率超标问题也成为了困扰。对于…

作者头像 李华
网站建设 2026/6/10 13:11:09

一文搞懂大模型并行计算:DP/PP/TP/EP原理与实践

本文详解了AI大模型训练的四种主流并行计算方式&#xff1a;数据并行(DP)、流水线并行(PP)、张量并行(TP)和专家并行(EP)。通过ZeRO优化技术减少内存占用&#xff0c;并介绍混合并行策略如3D并行。不同并行方式各有优劣&#xff0c;适用于不同场景&#xff0c;实际应用中常结合…

作者头像 李华