2023年12月7日发(作者:)

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

式)

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

验证客户端pom依赖

spring-boot-starter-web

mponents

httpclient

4.5.10

mponents

httpcore

4.4.12

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

验证方式包括跳过证书验证,也即是添加信任,就像浏览器访问自签名https服务时,页面会给出提示“您的链接不是私密连接”,点击了高

级,继续前往即是对该服务添加了信任,可以继续访问该网站服务,另外一种方式就是通过服务器证书来验证,下面就直接上代码

跳过证书验证方式

package mo;

import icateException;

import .X509Certificate;

import meVerifier;

import RLConnection;

import text;

import sion;

import anager;

import .X509TrustManager;

import nectionSocketFactory;

import ients;

import ;

import Factory;

import ;

import mponentsClientHttpRequestFactory;

import ent;

import mplate;

@Component

public class SkipVerifyRestTemplateBuilder {

private Logger logger = ger();

// 初始化ssl resttemplate

@Bean("skipVerifyRestTemplate")

public RestTemplate skipVerifyRestTemplate() {

RestTemplate rest = new RestTemplate();

SSLConnectionSocketFactory buildSSLSocketFactory = null;

try {

buildSSLSocketFactory = SLSocketFactory();

} catch (Exception e) {

("", e);

}

HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(

().setSSLSocketFactory(buildSSLSocketFactory).build());

nectionRequestTimeout(1000);

nectTimeout(1000);

uestFactory(factory);

return rest;

} private SSLConnectionSocketFactory buildSSLSocketFactory() throws Exception {

SSLContext sslContext = tance("SSL");

// 设置信任证书(绕过TrustStore验证)

(null, new TrustManager[] { new AuthX509TrustManager() }, null);

aultSSLSocketFactory(ketFactory());

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 icateException {

return;

}

public void checkClientTrusted(X509Certificate[] certs, String authType) throws CertificateException {

return;

}

}

}

第二种跳过证书验证方式

package mo;

import ption;

import re;

import icateException;

import .X509Certificate;

import ist;

import ;

import meVerifier;

import RLConnection;

import text;

import sion;

import nectionSocketFactory;

import trategy;

import ients;

import texts;

import ;

import mponentsClientHttpRequestFactory;

import ent;

import mplate;

@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

tackTrace();

}

HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory(

().setSSLSocketFactory(ssLSocketFactory).build());

// 设置传递数据超时时长

dTimeout(1000);

uestFactory(httpRequestFactory);

// 如果返回的数据非json则可能需要添加对应httpmessageconverter

// Jaxb2RootElementHttpMessageConverter converter = new

// Jaxb2RootElementHttpMessageConverter();

// // List mediaTypeList = new ArrayList<>(); // (portedMediaTypes()); // (_HTML); // portedMediaTypes(mediaTypeList); // // List> list = new ArrayList<>(); // (converter); // sageConverters(list); return rest; } public SSLConnectionSocketFactory sslFactory(String keyStoreType, String keyPassword) { SSLConnectionSocketFactory sslConnectionSocketFactory = null; try { SSLContext sslcontext = () // //忽略掉对服务器端证书的校验 .loadTrustMaterial(new TrustStrategy() { @Override public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException { return true; } }).build(); sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null, aultHostnameVerifier()); } catch (Exception e) { tackTrace(); } return sslConnectionSocketFactory; }}根据证书验证package mo;import ption;import re;import ist;import ;import meVerifier;import text;import sion;import nectionSocketFactory;import elfSignedStrategy;import ients;import texts;import ;import Factory;import ;import ;import ce;import mponentsClientHttpRequestFactory;import ent;import mplate;@Componentpublic class VerifyCaRestTemplateBuilder { private Logger logger = ger(); @Value("classpath:cert.p12") private Resource certFile; @Bean("verifyCaRestTemplate") public RestTemplate verifyCaRestTemplate() { RestTemplate rest = new RestTemplate(); SSLConnectionSocketFactory ssLSocketFactory = null; try { ssLSocketFactory = sslFactory("PKCS12", "abc123"); } catch (Exception e) { ("", e); } HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory( ().setSSLSocketFactory(ssLSocketFactory).build()); // 设置传递数据超时时长 dTimeout(1000); uestFactory(httpRequestFactory);

// 如果返回的数据非json则可能需要添加对应httpmessageconverter

// Jaxb2RootElementHttpMessageConverter converter = new

// Jaxb2RootElementHttpMessageConverter();

//

// List mediaTypeList = new ArrayList<>();

// (portedMediaTypes());

// (_HTML);

// portedMediaTypes(mediaTypeList);

//

// List> list = new ArrayList<>();

// (converter);

// sageConverters(list);

return rest;

}

public SSLConnectionSocketFactory sslFactory(String keyStoreType, String keyPassword) {

SSLConnectionSocketFactory sslConnectionSocketFactory = null;

try {

KeyStore keyStore = null;

try {

keyStore = tance(keyStoreType);

(utStream(), Array());

} catch (IOException e) {

("", 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 = ()

.loadTrustMaterial(e(), Array(), new TrustSelfSignedStrategy())

.loadKeyMaterial(keyStore, Array()).build();

sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null, hv);

} catch (Exception e) {

tackTrace();

}

return sslConnectionSocketFactory;

}

}

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

rUnverifiedException: Certificate for doesn't match any of the subject alternative names: []

测试controller

package mo;

import ce;

import seEntity;

import ller;

import tMapping;

import seBody;

import mplate;

@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 = Entity("127.0.0.1:8443/test", , new Object[] {}); return y(); } @RequestMapping("/secondskip") @ResponseBody public String secondSkipVerifyCert() { ResponseEntity forEntity = Entity("127.0.0.1:8443/test", , new Object[] {}); return y(); } @RequestMapping("/verify") @ResponseBody public String verifyCert() { ResponseEntity forEntity = Entity("127.0.0.1:8443/test", , new Object[] {}); return y(); }}可分别访问当前客户端的skip、secondskip、verify验证结果