java客户端验证https连接(忽略证书验证和证书验证两种方式)

您所在的位置:网站首页 关闭证书检查 java客户端验证https连接(忽略证书验证和证书验证两种方式)

java客户端验证https连接(忽略证书验证和证书验证两种方式)

2024-07-16 02:04| 来源: 网络整理| 查看: 265

首先根据如下操作生成证书,配置springboot https,生成一个简单的https web服务

https://www.cnblogs.com/qq931399960/p/11889349.html

验证客户端pom依赖

org.springframework.boot spring-boot-starter-web org.apache.httpcomponents httpclient 4.5.10 org.apache.httpcomponents httpcore 4.4.12

httpclient和httpcore版本要对应,否则可能会出现异常

验证方式包括跳过证书验证,也即是添加信任,就像浏览器访问自签名https服务时,页面会给出提示“您的链接不是私密连接”,点击了高级,继续前往即是对该服务添加了信任,可以继续访问该网站服务,另外一种方式就是通过服务器证书来验证,下面就直接上代码

跳过证书验证方式

package com.demo.bootdemo; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.impl.client.HttpClients; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Bean; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; @Component public class SkipVerifyRestTemplateBuilder { private Logger logger = LoggerFactory.getLogger(SkipVerifyRestTemplateBuilder.class); // 初始化ssl resttemplate @Bean("skipVerifyRestTemplate") public RestTemplate skipVerifyRestTemplate() { RestTemplate rest = new RestTemplate(); SSLConnectionSocketFactory buildSSLSocketFactory = null; try { buildSSLSocketFactory = this.buildSSLSocketFactory(); } catch (Exception e) { logger.error("", e); } HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory( HttpClients.custom().setSSLSocketFactory(buildSSLSocketFactory).build()); factory.setConnectionRequestTimeout(1000); factory.setConnectTimeout(1000); rest.setRequestFactory(factory); return rest; } private SSLConnectionSocketFactory buildSSLSocketFactory() throws Exception { SSLContext sslContext = SSLContext.getInstance("SSL"); // 设置信任证书(绕过TrustStore验证) sslContext.init(null, new TrustManager[] { new AuthX509TrustManager() }, null); HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory()); SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext, new String[] { "TLSv1" }, null, new HostnameVerifier() { // hostname,默认返回true,不验证hostname @Override public boolean verify(String urlHostName, SSLSession session) { return true; } }); return sslConnectionSocketFactory; } private class AuthX509TrustManager implements TrustManager, X509TrustManager { public X509Certificate[] getAcceptedIssuers() { return null; } public void checkServerTrusted(X509Certificate[] certs, String authType) throws java.security.cert.CertificateException { return; } public void checkClientTrusted(X509Certificate[] certs, String authType) throws CertificateException { return; } } }

第二种跳过证书验证方式

package com.demo.bootdemo; import java.io.IOException; import java.security.KeyStore; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.List; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.conn.ssl.TrustStrategy; import org.apache.http.impl.client.HttpClients; import org.apache.http.ssl.SSLContexts; import org.springframework.context.annotation.Bean; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; @Component public class SecondSkipVerifyRestTemplateBuilder { @Bean("secondSkipRestTemplate") public RestTemplate verifyCaRestTemplate() { RestTemplate rest = new RestTemplate(); SSLConnectionSocketFactory ssLSocketFactory = null; try { ssLSocketFactory = sslFactory("PKCS12", "abc123"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory( HttpClients.custom().setSSLSocketFactory(ssLSocketFactory).build()); // 设置传递数据超时时长 httpRequestFactory.setReadTimeout(1000); rest.setRequestFactory(httpRequestFactory); // 如果返回的数据非json则可能需要添加对应httpmessageconverter // Jaxb2RootElementHttpMessageConverter converter = new // Jaxb2RootElementHttpMessageConverter(); // // List mediaTypeList = new ArrayList(); // mediaTypeList.addAll(converter.getSupportedMediaTypes()); // mediaTypeList.add(MediaType.TEXT_HTML); // converter.setSupportedMediaTypes(mediaTypeList); // // List> list = new ArrayList(); // list.add(converter); // rest.setMessageConverters(list); return rest; } public SSLConnectionSocketFactory sslFactory(String keyStoreType, String keyPassword) { SSLConnectionSocketFactory sslConnectionSocketFactory = null; try { KeyStore keyStore = null; try { keyStore = KeyStore.getInstance(keyStoreType); keyStore.load(certFile.getInputStream(), keyPassword.toCharArray()); } catch (IOException e) { logger.error("", e); } HostnameVerifier hv = new HostnameVerifier() { @Override public boolean verify(String urlHostName, SSLSession session) { // 如果需要验证https域名,可以在该处做判断,如果访问的hostname与判断不一致,则会出现如下异常 // if("localhost".equals(urlHostName)) { // return true; // }else { // return false; // } // 此处不校验hostname,接收所有hostname,只是用于测试。 return true; } }; SSLContext sslcontext = SSLContexts.custom() .loadTrustMaterial(certFile.getFile(), keyPassword.toCharArray(), new TrustSelfSignedStrategy()) .loadKeyMaterial(keyStore, keyPassword.toCharArray()).build(); sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null, hv); } catch (Exception e) { e.printStackTrace(); } return sslConnectionSocketFactory; } }

 注:在上述HostnameVerifier 中,可以验证hostname有效性,如果无效,返回fase,则会出现类似以下异常

javax.net.ssl.SSLPeerUnverifiedException: Certificate for doesn't match any of the subject alternative names: []

测试controller

package com.demo.bootdemo; import javax.annotation.Resource; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.client.RestTemplate; @Controller public class HttpsSendController { @Resource(name = "skipVerifyRestTemplate") private RestTemplate skipVerifyRestTemplate; @Resource(name = "verifyCaRestTemplate") private RestTemplate verifyCaRestTemplate; @Resource(name = "secondSkipRestTemplate") private RestTemplate secondSkipRestTemplate; @RequestMapping("/skip") @ResponseBody public String skipVerifyCert() { ResponseEntity forEntity = skipVerifyRestTemplate.getForEntity("https://127.0.0.1:8443/test", String.class, new Object[] {}); return forEntity.getBody(); } @RequestMapping("/secondskip") @ResponseBody public String secondSkipVerifyCert() { ResponseEntity forEntity = skipVerifyRestTemplate.getForEntity("https://127.0.0.1:8443/test", String.class, new Object[] {}); return forEntity.getBody(); } @RequestMapping("/verify") @ResponseBody public String verifyCert() { ResponseEntity forEntity = verifyCaRestTemplate.getForEntity("https://127.0.0.1:8443/test", String.class, new Object[] {}); return forEntity.getBody(); } }

可分别访问当前客户端的skip、secondskip、verify验证结果

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3