您的位置:首页 > 理论基础 > 计算机网络

【fastweixin框架教程3】JAVA进行HTTPS网站访问,PKIX path building failed解决方法

2016-05-05 13:29 639 查看
  上几篇文章我们谈到fastweixin使用问题和修改。

  今天的问题就是使用JAVA访问HTTPS网站时候经常出现javax.net.ssl.SSLHandshakeException

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target  

    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)  

    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(Unknown Source)  

    at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)  

    at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)  

    at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(Unknown Source)  

    at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(Unknown Source)  

    at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Unknown Source)  

    at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Unknown Source)  

    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source)  

    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)  

    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown Source)  

    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown Source)  

    at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)  

    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)  

    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)  

    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(Unknown Source)  

  

  对于这个问题,一般采用两种方法:1、导入疼讯网站证书 2、修改代码

 考虑到很多人的服务器并不是自主控制,无法进行第一种方法,导入证书,下面决定修改原框架代码以便适应HTTPS。

package com.fastwixinextend;

import com.github.sd4324530.fastweixin.util.NetWorkCenter;

import java.io.File;
import java.io.IOException;

import java.net.URL;

import java.nio.charset.Charset;

import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;

import java.util.List;

import javax.net.ssl.SSLContext;

import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.utils.HttpClientUtils;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* com.github.sd4324530.fastweixin.util.NetWorkCenter 修改版本
* http://blog.csdn.net/xiaoxian8023/article/details/49865335 *
* 将 com.github.sd4324530.fastweixin.util修改 public final class NetWorkCenter
* extends MyNetWorkCenter {
*
* 采用https的访问协议获取新的AccessToken时,总是出现异常: javax.net.ssl.SSLHandshakeException:
* sun.security.validator.ValidatorException: PKIX path building failed:
* sun.security.provider.certpath.SunCertPathBuilderException: unable to find
* valid certification path to requested target 之后在网上找了很多例子,最后摘了一个不需要证书的例子:
*/
public class MyNetWorkCenter {

/**
* 默认连接超时时间(毫秒) 由于目前的设计原因,该变量定义为静态的,超时时间不能针对每一次的请求做定制 备选优化方案:
* 1.考虑是否重新设计这个工具类,每次请求都需要创建一个实例; 2.请求方法里加入超时时间参数
* 或者说是否没必要定制,10秒是一个比较适中的选择,但有些请求可能就是需要快速给出结果T_T
*/
public static final int CONNECT_TIMEOUT = 10 * 1000;
private static final Logger LOG
= LoggerFactory.getLogger(NetWorkCenter.class);
private static final Charset UTF_8 = Charset.forName("UTF-8");

public MyNetWorkCenter() {
super();
}

/**
* 自定义HTTP响应回调接口,用于兼容jdk6
*
* @author peiyu
* @since 1.1
*/
//  @FunctionalInterface
public interface ResponseCallback {

/**
* 响应后回调方法
*
* @param resultCode 响应结果码,比如200成功,404不存在,500服务器异常等
* @param resultJson 响应内容,目前支持JSON字符串
*/
void onResponse(int resultCode, String resultJson);
}

/**
* 标识HTTP请求类型枚举
*
* @author peiyu
* @since 1.0
*/
public enum RequestMethod {
/**
* HTTP GET请求 一般对应的是查询业务接口
*/
GET,
/**
* HTTP POST请求 一般对应的是新增业务接口 只是一般都通用这个请求方式来处理一切接口了T_T
*/
POST,
/**
* HTTP PUT请求,用的太少,暂不支持 一般对应的是更新业务接口
*/
PUT,
/**
* HTTP DELETE请求,用的太少,暂不支持 一般对应的是删除业务接口
*/
DELETE;
private static final long serialVersionUID = 1L;
}

/**
* 处理HTTP请求 基于org.apache.http.client包做了简单的二次封装 对于子函数,修改doRequest() String
* ishttp=url.toLowerCase(); if(ishttp.startsWith("https") ||
* ishttp.startsWith("HTTPS")) { doRequestSSH(method, url, paramData,
* fileList, callback); return; }
*
* @param method HTTP请求类型
* @param url 请求对应的URL地址
* @param paramData 请求所带参数,目前支持JSON格式的参数
* @param fileList 需要一起发送的文件列表
* @param callback
* 请求收到响应后回调函数,参数有2个,第一个为resultCode,即响应码,比如200为成功,404为不存在,500为服务器发生错误;
* 第二个为resultJson,即响应回来的数据报文
*/
public static void doRequestSSH(final RequestMethod method, final String url,
final String paramData,
final List<File> fileList,
final ResponseCallback callback) {
//如果url没有传入,则直接返回
if (null == url || url.isEmpty()) {
LOG.warn("The url is null or empty!!You must give it to me!OK?");
return;
}

//默认期望调用者传入callback函数
boolean haveCallback = true;
/*
* 支持不传回调函数,只输出一个警告,并改变haveCallback标识
* 用于一些不需要后续处理的请求,比如只是发送一个心跳包等等
*/
if (null == callback) {
LOG.warn("--------------no callback block!--------------");
haveCallback = false;
}

LOG.debug("-----------------请求地址:{}-----------------", url);
//配置请求参数
RequestConfig config
= RequestConfig.custom().setConnectionRequestTimeout(CONNECT_TIMEOUT).setConnectTimeout(CONNECT_TIMEOUT).setSocketTimeout(CONNECT_TIMEOUT).build();

SSLContext sslcontext = null;

// 设置协议http和https对应的处理socket链接工厂的对象
try {
sslcontext = SslUtils.createIgnoreVerifySSL();
} catch (KeyManagementException e) {
} catch (NoSuchAlgorithmException e) {
}
Registry<ConnectionSocketFactory> socketFactoryRegistry
= RegistryBuilder.<ConnectionSocketFactory>create().register("http",
PlainConnectionSocketFactory.INSTANCE).register("https",
new SSLConnectionSocketFactory(sslcontext)).build();
PoolingHttpClientConnectionManager connManager
= new PoolingHttpClientConnectionManager(socketFactoryRegistry);
HttpClients.custom().setConnectionManager(connManager);

//创建自定义的httpclient对象
HttpClientBuilder HttpClientbuilder = HttpClients.custom().setConnectionManager(connManager);
HttpClientbuilder.setDefaultRequestConfig(config);
CloseableHttpClient client = HttpClientbuilder.build();
//CloseableHttpClient client = HttpClientBuilder.create().setDefaultRequestConfig(config).build();
HttpUriRequest request = null;
switch (method) {
case GET:
String getUrl = url;
if (null != paramData) {
getUrl += "?" + paramData;
}
request = new HttpGet(getUrl);
break;
case POST:
LOG.debug("请求入参:");
LOG.debug(paramData);
request = new HttpPost(url);
//上传文件
if (null != fileList && !fileList.isEmpty()) {
LOG.debug("上传文件...");
MultipartEntityBuilder builder
= MultipartEntityBuilder.create();
for (File file : fileList) {
//只能上传文件哦 ^_^
if (file.isFile()) {
FileBody fb = new FileBody(file);
builder.addPart("media", fb);
} else { //如果上传内容有不是文件的,则不发起本次请求
LOG.warn("The target '{}' not a file,please check and try again!",
file.getPath());
return;
}
}
if (null != paramData) {
builder.addPart("description",
new StringBody(paramData, ContentType.APPLICATION_JSON));
}
((HttpPost) request).setEntity(builder.build());
} else //不上传文件的普通请求
{
if (null != paramData) {
// 目前支持JSON格式的数据
StringEntity jsonEntity
= new StringEntity(paramData, ContentType.APPLICATION_JSON);
((HttpPost) request).setEntity(jsonEntity);
}
}
break;
case PUT:
case DELETE:
default:
LOG.warn("-----------------请求类型:{} 暂不支持-----------------",
method.toString());
break;
}
CloseableHttpResponse response = null;
try {
URL u = new URL(url);
if ("https".equalsIgnoreCase(u.getProtocol())) {
SslUtils.ignoreSsl();
}
long start = System.currentTimeMillis();
//发起请求
response = client.execute(request);
long time = System.currentTimeMillis() - start;
LOG.debug("本次请求'{}'耗时:{}ms",
url.substring(url.lastIndexOf("/") + 1, url.length()),
time);
int resultCode = response.getStatusLine().getStatusCode();
HttpEntity entity = response.getEntity();
//此流不是操作系统资源,不用关闭,ByteArrayOutputStream源码里close也是个空方法-0_0-
//            OutputStream os = new ByteArrayOutputStream();
//            entity.writeTo(os);
//            String resultJson = os.toString();
String resultJson = EntityUtils.toString(entity, UTF_8);
//返回码200,请求成功;其他情况都为请求出现错误
if (HttpStatus.SC_OK == resultCode) {
LOG.debug("-----------------请求成功-----------------");
LOG.debug("响应结果:");
LOG.debug(resultJson);
if (haveCallback) {
callback.onResponse(resultCode, resultJson);
}
} else if (haveCallback) {
LOG.warn("-----------------请求出现错误,错误码:{}-----------------",
resultCode);
callback.onResponse(resultCode, resultJson);
}
} catch (ClientProtocolException e) {
LOG.error("ClientProtocolException:", e);
LOG.warn("-----------------请求出现异常:{}-----------------",
e.toString());
if (haveCallback) {
callback.onResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR,
e.toString());
}
} catch (IOException e) {
LOG.error("IOException:", e);
LOG.warn("-----------------请求出现IO异常:{}-----------------",
e.toString());
if (haveCallback) {
callback.onResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR,
e.toString());
}
} catch (Exception e) {
LOG.error("Exception:", e);
LOG.warn("-----------------请求出现其他异常:{}-----------------",
e.toString());
if (haveCallback) {
callback.onResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR,
e.toString());
}
} finally {
//abort the request
if (null != request && !request.isAborted()) {
request.abort();
}
//close the connection
HttpClientUtils.closeQuietly(client);
HttpClientUtils.closeQuietly(response);
}
}
}


原文件NetWorkCenter 修改如下:

package com.github.sd4324530.fastweixin.util;

import com.fastwixinextend.MyNetWorkCenter.RequestMethod;
import com.fastwixinextend.MyNetWorkCenter.ResponseCallback;

import com.github.sd4324530.fastweixin.api.response.BaseResponse;

import com.fastwixinextend.MyNetWorkCenter;

import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.utils.HttpClientUtils;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Map;

/**
* HTTP请求客户端操作类,基于org.apache.http.client包4.4.x版本实现
*/
public final class NetWorkCenter extends MyNetWorkCenter {

/**
* 默认连接超时时间(毫秒) 由于目前的设计原因,该变量定义为静态的,超时时间不能针对每一次的请求做定制 备选优化方案:
* 1.考虑是否重新设计这个工具类,每次请求都需要创建一个实例; 2.请求方法里加入超时时间参数
* 或者说是否没必要定制,10秒是一个比较适中的选择,但有些请求可能就是需要快速给出结果T_T
*/
public static final int CONNECT_TIMEOUT = 10 * 1000;
/**
* 日志输出组件
*/
private static final Logger LOG = LoggerFactory.getLogger(NetWorkCenter.class);
private static final Charset UTF_8 = Charset.forName("UTF-8");

/**
* 私有化构造器 不允许外界创建实例
*/
private NetWorkCenter() {
LOG.warn("Oh,my god!!!How do you call this method?!");
LOG.warn("You shouldn't create me!!!");
LOG.warn("Look my doc again!!!");
}

/**
* 发起HTTP POST同步请求 jdk8使用函数式方式处理请求结果 jdk6使用内部类方式处理请求结果
*
* @param url 请求对应的URL地址
* @param paramData 请求所带参数,目前支持JSON格式的参数
* @param callback
* 请求收到响应后回调函数,参数有2个,第一个为resultCode,即响应码,比如200为成功,404为不存在,500为服务器发生错误;
* 第二个为resultJson,即响应回来的数据报文
*/
public static void post(String url, String paramData,
ResponseCallback callback) {
post(url, paramData, null, callback);
}

public static BaseResponse post(String url, String paramData) {
final BaseResponse[] response = new BaseResponse[]{null};
post(url, paramData, new ResponseCallback() {
@Override
public void onResponse(int resultCode, String resultJson) {
if (200 == resultCode) {
BaseResponse r = JSONUtil.toBean(resultJson, BaseResponse.class);
r.setErrmsg(resultJson);
response[0] = r;
} else {//请求本身就失败了
response[0] = new BaseResponse();
response[0].setErrcode(String.valueOf(resultCode));
response[0].setErrmsg("请求失败");
}
}
});
return response[0];
}

/**
* 发起HTTP POST同步请求 jdk8使用函数式方式处理请求结果 jdk6使用内部类方式处理请求结果
*
* @param url 请求对应的URL地址
* @param paramData 请求所带参数,目前支持JSON格式的参数
* @param fileList 需要一起发送的文件列表
* @param callback
* 请求收到响应后回调函数,参数有2个,第一个为resultCode,即响应码,比如200为成功,404为不存在,500为服务器发生错误;
* 第二个为resultJson,即响应回来的数据报文
*/
public static void post(String url, String paramData, List<File> fileList,
ResponseCallback callback) {
doRequest(MyNetWorkCenter.RequestMethod.POST, url, paramData, fileList, callback);
}

public static BaseResponse post(String url, String paramData, List<File> fileList) {
final BaseResponse[] response = new BaseResponse[]{null};
post(url, paramData, fileList, new ResponseCallback() {
@Override
public void onResponse(int resultCode, String resultJson) {
if (200 == resultCode) {
BaseResponse r = JSONUtil.toBean(resultJson, BaseResponse.class);
if (StrUtil.isBlank(r.getErrcode())) {
r.setErrcode("0");
}
r.setErrmsg(resultJson);
response[0] = r;
} else {//请求本身就失败了
response[0] = new BaseResponse();
response[0].setErrcode(String.valueOf(resultCode));
response[0].setErrmsg("请求失败");
}
}
});
return response[0];
}

/**
* 发起HTTP GET同步请求 jdk8使用函数式方式处理请求结果 jdk6使用内部类方式处理请求结果
*
* @param url 请求对应的URL地址
* @param paramMap GET请求所带参数Map,即URL地址问号后面所带的键值对,很蛋疼的实现方式,后续得改进,还没什么好的方案
* @param callback
* 请求收到响应后回调函数,参数有2个,第一个为resultCode,即响应码,比如200为成功,404为不存在,500为服务器发生错误;
* 第二个为resultJson,即响应回来的数据报文
*/
public static void get(String url, Map<String, String> paramMap, ResponseCallback callback) {
String paramData = null;
if (null != paramMap && !paramMap.isEmpty()) {
StringBuilder buffer = new StringBuilder();
//根据传进来的参数拼url后缀- -!
for (Map.Entry<String, String> param : paramMap.entrySet()) {
buffer.append(param.getKey()).append("=").append(param.getValue()).append("&");
}
//去掉最后一个&符号
paramData = buffer.substring(0, buffer.length() - 1);
}
doRequest(MyNetWorkCenter.RequestMethod.GET, url, paramData, null, callback);
}

public static BaseResponse get(String url) {
final BaseResponse[] response = new BaseResponse[]{null};
doRequest(MyNetWorkCenter.RequestMethod.GET, url, null, null, new ResponseCallback() {
@Override
public void onResponse(int resultCode, String resultJson) {
if (200 == resultCode) {
BaseResponse r = JSONUtil.toBean(resultJson, BaseResponse.class);
if (StrUtil.isBlank(r.getErrcode())) {
r.setErrcode("0");
}
r.setErrmsg(resultJson);
response[0] = r;
} else {//请求本身就失败了
response[0] = new BaseResponse();
response[0].setErrcode(String.valueOf(resultCode));
response[0].setErrmsg("请求失败");
}
}
});
return response[0];
}

/**
* 处理HTTP请求 基于org.apache.http.client包做了简单的二次封装
*
* @param method HTTP请求类型
* @param url 请求对应的URL地址
* @param paramData 请求所带参数,目前支持JSON格式的参数
* @param fileList 需要一起发送的文件列表
* @param callback
* 请求收到响应后回调函数,参数有2个,第一个为resultCode,即响应码,比如200为成功,404为不存在,500为服务器发生错误;
* 第二个为resultJson,即响应回来的数据报文
*/
private static void doRequest(final RequestMethod method, final String url,
final String paramData, final List<File> fileList, final ResponseCallback callback) {
//如果url没有传入,则直接返回
if (null == url || url.isEmpty()) {
LOG.warn("The url is null or empty!!You must give it to me!OK?");
return;
}
String ishttp = url.toLowerCase();
if (ishttp.startsWith("https") || ishttp.startsWith("HTTPS")) {
doRequestSSH(method, url, paramData, fileList, callback);
return;
}
//默认期望调用者传入callback函数
boolean haveCallback = true;
/*
* 支持不传回调函数,只输出一个警告,并改变haveCallback标识
* 用于一些不需要后续处理的请求,比如只是发送一个心跳包等等
*/
if (null == callback) {
LOG.warn("--------------no callback block!--------------");
haveCallback = false;
}

LOG.debug("-----------------请求地址:{}-----------------", url);
//配置请求参数
RequestConfig config = RequestConfig.custom().setConnectionRequestTimeout(CONNECT_TIMEOUT).setConnectTimeout(CONNECT_TIMEOUT).setSocketTimeout(CONNECT_TIMEOUT).build();
CloseableHttpClient client = HttpClientBuilder.create().setDefaultRequestConfig(config).build();
HttpUriRequest request = null;
switch (method) {
case GET:
String getUrl = url;
if (null != paramData) {
getUrl += "?" + paramData;
}
request = new HttpGet(getUrl);
break;
case POST:
LOG.debug("请求入参:");
LOG.debug(paramData);
request = new HttpPost(url);
//上传文件
if (null != fileList && !fileList.isEmpty()) {
LOG.debug("上传文件...");
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
for (File file : fileList) {
//只能上传文件哦 ^_^
if (file.isFile()) {
FileBody fb = new FileBody(file);
builder.addPart("media", fb);
} else {//如果上传内容有不是文件的,则不发起本次请求
LOG.warn("The target '{}' not a file,please check and try again!", file.getPath());
return;
}
}
if (null != paramData) {
builder.addPart("description", new StringBody(paramData, ContentType.APPLICATION_JSON));
}
((HttpPost) request).setEntity(builder.build());
} else//不上传文件的普通请求
{
if (null != paramData) {
// 目前支持JSON格式的数据
StringEntity jsonEntity = new StringEntity(paramData, ContentType.APPLICATION_JSON);
((HttpPost) request).setEntity(jsonEntity);
}
}
break;
case PUT:
case DELETE:
default:
LOG.warn("-----------------请求类型:{} 暂不支持-----------------", method.toString());
break;
}
CloseableHttpResponse response = null;
try {
long start = System.currentTimeMillis();
//发起请求
response = client.execute(request);
long time = System.currentTimeMillis() - start;
LOG.debug("本次请求'{}'耗时:{}ms", url.substring(url.lastIndexOf("/") + 1, url.length()), time);
int resultCode = response.getStatusLine().getStatusCode();
HttpEntity entity = response.getEntity();
//此流不是操作系统资源,不用关闭,ByteArrayOutputStream源码里close也是个空方法-0_0-
//            OutputStream os = new ByteArrayOutputStream();
//            entity.writeTo(os);
//            String resultJson = os.toString();
String resultJson = EntityUtils.toString(entity, UTF_8);
//返回码200,请求成功;其他情况都为请求出现错误
if (HttpStatus.SC_OK == resultCode) {
LOG.debug("-----------------请求成功-----------------");
LOG.debug("响应结果:");
LOG.debug(resultJson);
if (haveCallback) {
callback.onResponse(resultCode, resultJson);
}
} else if (haveCallback) {
LOG.warn("-----------------请求出现错误,错误码:{}-----------------", resultCode);
callback.onResponse(resultCode, resultJson);
}
} catch (ClientProtocolException e) {
LOG.error("ClientProtocolException:", e);
LOG.warn("-----------------请求出现异常:{}-----------------", e.toString());
if (haveCallback) {
callback.onResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR, e.toString());
}
} catch (IOException e) {
LOG.error("IOException:", e);
LOG.warn("-----------------请求出现IO异常:{}-----------------", e.toString());
if (haveCallback) {
callback.onResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR, e.toString());
}
} catch (Exception e) {
LOG.error("Exception:", e);
LOG.warn("-----------------请求出现其他异常:{}-----------------", e.toString());
if (haveCallback) {
callback.onResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR, e.toString());
}
} finally {
//abort the request
if (null != request && !request.isAborted()) {
request.abort();
}
//close the connection
HttpClientUtils.closeQuietly(client);
HttpClientUtils.closeQuietly(response);
}
}

}


package com.fastwixinextend;

import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
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;

public class SslUtils {

/**
* 绕过验证
*
* @return
* @throws NoSuchAlgorithmException
* @throws KeyManagementException
*/
public static SSLContext createIgnoreVerifySSL() throws NoSuchAlgorithmException, KeyManagementException {
SSLContext sc = SSLContext.getInstance("SSLv3");

// 实现一个X509TrustManager接口,用于绕过验证,不用修改里面的方法
X509TrustManager trustManager = new X509TrustManager() {
@Override
public void checkClientTrusted(
java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
String paramString) throws CertificateException {
}

@Override
public void checkServerTrusted(
java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
String paramString) throws CertificateException {
}

@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
};

sc.init(null, new TrustManager[]{trustManager}, null);
return sc;
}

private static void trustAllHttpsCertificates() throws Exception {
TrustManager[] trustAllCerts = new TrustManager[1];
TrustManager tm = new miTM();
trustAllCerts[0] = tm;
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, null);
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
}

static class miTM implements TrustManager, X509TrustManager {

public X509Certificate[] getAcceptedIssuers() {
return null;
}

public boolean isServerTrusted(X509Certificate[] certs) {
return true;
}

public boolean isClientTrusted(X509Certificate[] certs) {
return true;
}

public void checkServerTrusted(X509Certificate[] certs, String authType)
throws CertificateException {
return;
}

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

/**
* 忽略HTTPS请求的SSL证书,必须在openConnection之前调用
*
* @throws Exception
*/
public static void ignoreSsl() throws Exception {
HostnameVerifier hv = new HostnameVerifier() {
public boolean verify(String urlHostName, SSLSession session) {
System.out.println("Warning: URL Host: " + urlHostName + " vs. " + session.getPeerHost());
return true;
}
};
trustAllHttpsCertificates();
HttpsURLConnection.setDefaultHostnameVerifier(hv);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  JAVA PKIX https