jodd忽略ssl证书_关于java访问https资源时,忽略证书信任问题
java程序在访问https资源时,出现报错
sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
这本质上,是java在访问https资源时的证书信任问题。
如何解决这个问题呢?
解决这个问题前,要了解
1)https通信过程
客户端在使用HTTPS方式与Web服务器通信时有以下几个步骤,如图所示。
(1)客户使用https的URL访问Web服务器,要求与Web服务器建立SSL连接。
(2)Web服务器收到客户端请求后,会将网站的证书信息(证书中包含公钥)传送一份给客户端。
(3)客户端的浏览器与Web服务器开始协商SSL连接的安全等级,也就是信息加密的等级。
(4)客户端的浏览器根据双方同意的安全等级,建立会话密钥,然后利用网站的公钥将会话密钥加密,并传送给网站。
(5)Web服务器利用自己的私钥解密出会话密钥。
(6)Web服务器利用会话密钥加密与客户端之间的通信。
2)java程序的证书信任规则
如上文所述,客户端会从服务端拿到证书信息。调用端(客户端)会有一个证书信任列表,拿到证书信息后,会判断该证书是否可信任。
如果是用浏览器访问https资源,发现证书不可信任,一般会弹框告诉用户,对方的证书不可信任,是否继续之类。
Java虚拟机并不直接使用操作系统的keyring,而是有自己的security manager。与操作系统类似,jdk的security manager默认有一堆的根证书信任。如果你的https站点证书是花钱申请的,被这些根证书所信任,那使用java来访问此https站点会非常方便。因此,如果用java访问https资源,发现证书不可信任,则会报文章开头说到的错误。
解决问题的方法
1)将证书导入到jdk的信任证书中(理论上应该可行,未验证)
2)在客户端(调用端)添加逻辑,忽略证书信任问题
第一种方法,需要在每台运行该java程序的机器上,都做导入操作,不方便部署,因此,采用第二种方法。下面贴下该方法对应的代码。
验证可行的代码
1)先实现验证方法
HostnameVerifier hv = new HostnameVerifier() {
public boolean verify(String urlHostName, SSLSession session) {
System.out.println("Warning: URL Host: " + urlHostName + " vs. "
+ session.getPeerHost());
return true;
}
};
private static void trustAllHttpsCertificates() throws Exception {
javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1];
javax.net.ssl.TrustManager tm = new miTM();
trustAllCerts[0] = tm;
javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext
.getInstance("SSL");
sc.init(null, trustAllCerts, null);
javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc
.getSocketFactory());
}
static class miTM implements javax.net.ssl.TrustManager,
javax.net.ssl.X509TrustManager {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public boolean isServerTrusted(
java.security.cert.X509Certificate[] certs) {
return true;
}
public boolean isClientTrusted(
java.security.cert.X509Certificate[] certs) {
return true;
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType)
throws java.security.cert.CertificateException {
return;
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType)
throws java.security.cert.CertificateException {
return;
}
}
2)在访问https资源前,调用
trustAllHttpsCertificates();
HttpsURLConnection.setDefaultHostnameVerifier(hv);
以下是一个具体的例子:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;
import org.apache.log4j.Logger;
import org.htmlparser.util.ParserException;
import com.xwtech.parser.GetRequestHtmlParser;
import com.xwtech.pojo.ExtendCandidate;
/*
* GET请求类
*/
public class GetRequest {
private String url = "https://b2b.10086.cn/b2b/main/viewNoticeContent.html?noticeBean.id=";
private Logger logger;
public GetRequest() {
logger = Logger.getLogger(GetRequest.class);
}
private static void trustAllHttpsCertificates() throws Exception {
javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1];
javax.net.ssl.TrustManager tm = new miTM();
trustAllCerts[0] = tm;
javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, null);
javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
}
public void getData(String id) {
this.url = url + id;
BufferedReader in = null;
HttpURLConnection conn = null;
String result = "";
try {
//该部分必须在获取connection前调用
trustAllHttpsCertificates();
HostnameVerifier hv = new HostnameVerifier() {
public boolean verify(String urlHostName, SSLSession session) {
logger.info("Warning: URL Host: " + urlHostName + " vs. " + session.getPeerHost());
return true;
}
};
HttpsURLConnection.setDefaultHostnameVerifier(hv);
conn = (HttpURLConnection)new URL(url).openConnection();
// 发送GET请求必须设置如下两行
conn.setDoInput(true);
conn.setRequestMethod("GET");
// flush输出流的缓冲
in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
logger.error("发送 GET 请求出现异常!\t请求ID:"+id+"\n"+e.getMessage()+"\n");
} finally {// 使用finally块来关闭输出流、输入流
try {
if (in != null) {
in.close();
}
} catch (IOException ex) {
logger.error("关闭数据流出错了!\n"+ex.getMessage()+"\n");
}
}
// 获得相应结果result,可以直接处理......
}
static class miTM implements javax.net.ssl.TrustManager, javax.net.ssl.X509TrustManager {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public boolean isServerTrusted(java.security.cert.X509Certificate[] certs) {
return true;
}
public boolean isClientTrusted(java.security.cert.X509Certificate[] certs) {
return true;
}
public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType)
throws java.security.cert.CertificateException {
return;
}
public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType)
throws java.security.cert.CertificateException {
return;
}
}
}
jodd忽略ssl证书_关于java访问https资源时,忽略证书信任问题相关推荐
- java在访问https资源时,忽略证书信任问题
java程序在访问https资源时,出现报错 sun.security.validator.ValidatorException: PKIX path building failed: sun.sec ...
- java生成电子证书_关于Java:使用Bouncycastle生成数字证书
经过研究,我确定,为了在Java中以编程方式生成和签署证书,我需要bouncycastle库. 不幸的是,图书馆似乎在最近的某个时候进行了大修. 现在不推荐使用它们的很多类,而我可以找到的所有简单易懂 ...
- 使用Java访问https接口javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
jdk1.6,证书:SHA256+TLSv1.2 使用Java访问https://**************** 接口 控制台提示握手失败错误:javax.net.ssl.SSLHandsh ...
- c# https请求忽略证书验证_C# httpwebrequest访问HTTPS错误处理方法
C# httpwebrequest访问HTTPS链接时遇到这个错误,但是如果我开抓包工具,比如filddler2,则POST返回正常 错误提示的Message为: 基础连接已经关闭: 发送时发生错误. ...
- java访问https链接下载图片
java访问https链接下载图片 一.通过maven引入https工具包 <dependency><groupId>org.apache.httpcomponents< ...
- MySql数据库记录相差14小时排错,使用Java访问Mysql数据库时出现时区异常的解决方案
最近遇到1个大坑,A系统迁移到B系统,2边系统 同1个字段 createTime 看到的不一致. 表象: A系统: 2019-6-10 17:34 B系统: 2019-6-11 .... 再次尝试: ...
- Java爬虫https网页内容报错SSLHandshakeException信任(忽略)所有SSL证书
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building f ...
- HttpClient访问https,设置忽略SSL证书验证
访问https时报错:sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provid ...
- java权限控制是什么_论Java访问权限控制的重要性
人在什么面前最容易失去抵抗力? 欢迎工作一到八年的Java工程师朋友们加入Java高级交流:854630135 本群提供免费的学习指导 架构资料 以及免费的解答 不懂得问题都可以在本群提出来 之后还会 ...
最新文章
- 使用etcd+confd管理nginx配置
- CentOS下命令行和桌面模式的切换方法
- Form_Form Builder Export导出为Excel(案例)
- 用vue实现模态框组件
- EasyVS 0.3版本发布 -- 给力变换vs编辑器主题
- 没有语言基础可以学python_没有Python语言基础可以学习深度学习吗?
- 链表面试题1:反转单链表,不带头结点。
- Some Principles
- php ssh 管理服务器,php 利用ssh执行远程或本地liunx服务器命令
- python 读excel一列_Python读取Excel一列并计算所有对象出现次数的方法
- python2.7入门---内置函数
- 02_Storm集群部署
- 【数据库系统设计】关系数据库简介(关系模型、关系模式、关系完整性、关系代数)
- 30种EMC标准电路分享,再不收藏就晚了!
- N1盒子刷机经验分享
- Java使用aspose将word文档转换为pdf
- 什么是虚拟内存?虚拟内存的原理
- 【干货】微博短视频去水印下载使用介绍
- R语言绘制股票K线图
- java个人博客系统代码下载_java个人博客系统代码
热门文章
- C#LeetCode刷题之#345-反转字符串中的元音字母​​​​​​​(Reverse Vowels of a String)
- 算法训练营 重编码_编码训练营后十四天如何找到工作
- deque冰淇淋_用冰淇淋解释组合爆炸:如何添加一点并获得很多
- debian下安装python虚拟环境
- 添加phpiredis扩展的时候报错
- 列表合并变种题,map()函数扩展
- Python线程安全问题及解决方法
- PAT-1002 写出这个数
- 纯CSS实现的滑动的可折叠菜单
- [机器学习-总结] 什么是准确率, 精确率,召回率和(精确率和召回率的调和平均)