文档章节

解析Java为什么不接受合法的HTTPS证书

joymufeng
 joymufeng
发布于 2017/09/07 20:23
字数 1533
阅读 1482
收藏 43

转载请注明joymufeng,欢迎访问PlayScala社区(http://www.playscala.cn/)

在我们使用Java调用远程接口或是抓取数据时经常会发生以下错误:

Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:387)
	at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292)
	at sun.security.validator.Validator.validate(Validator.java:260)
	at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324)
	at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:281)
	at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:136)
	at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1496)
	... 27 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
	at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
	at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
	at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:382)
	... 33 more

这个错误表明Java虚拟机在请求远程HTTPS服务器时无法验证证书的有效性,由于担心HTTPS中间人劫持,所以抛出错误警告调用者。可是奇怪的是这个HTTPS链接在浏览器中可以被正确访问,这是为什么呢?别急,听我慢慢道来。

什么是HTTPS/SSL证书?

HTTPS/SSL证书是由权威CA(Certificate Authority)机构颁发,主要用于服务器(应用)数据传输链路加密和身份认证,以及绑定网站域名。主要有EV SSL证书(Extended Validation SSL),OV SSL证书(Organization Validation SSL)和DV SSL证书(Domain Validation SSL)等。不同的证书类型在浏览器标识上会享受不同的待遇,例如EV、OV证书在浏览器地址栏上会显示企业名称,当然也意味着你在向CA机构申请证书时要付更多的钱,走更多的审核流程。通常DV证书就足够用了,审核流程简单,并且很便宜。

我们上面说到HTTPS/SSL证书是由CA机构颁发的,为了方便运营,CA机构下面还有很多的代理商,这些代理商就是所谓的中间证书颁发机构(Intermediate Certificate Authority),一些大的代理商下面还会继续设置代理商。通常我们的证书都是在代理商或者叫中间证书颁发机构那里申请的。

如何验证证书的有效性?

HTTPS/SSL证书是一种非对称加密技术,HTTPS/SSL证书中包含了所有者的一些基本信息和对外公开的公钥,也就是说HTTPS/SSL证书其实就是所有者的一张名片,但是谁能证明这张名片上的信息是否属实呢? 就像是你拿着一个破手镯,到马路上然后逢人就说"我是马云私生子,看,这是他留给我的手镯,上面还有他的签名。",显然不会有人相信你。但是如果马云站出来,一把抢过手镯仔细端详一番后,抱着你痛哭流涕,那么这个手镯确实可以证明你是马云私生子。HTTPS/SSL证书的作用就像这个手镯,需要经过权威机构认证,通过了认证才会得到大家的认可。所以你的证书需要经过你的代理商认证,代理商的证书需要经过父级代理商认证,... ,这样层层认证一直到顶层的CA机构。所以:

HTTPS/SSL证书其实是一个证书链,这条链上的所有证书均合法才能表明证书本身的合法性。

Java的HTTPS/SSL证书错误分析

搞清楚证书链概念后我们再回头看一下本文开头的错误,其实原因很简单。浏览器成功地完成了整条证书链的校验,所以认为证书是合法的;而在Java中未能完成整条证书链的校验,例如无法验证某个中间证书颁发机构的合法性,所以导致最终认证失败。例如域名chatbot.cn的证书链如下:

中间证书COMODO RSA Domain Validation Secure Server CA的指纹为:

‎33 9c dd 57 cf d5 b1 41 16 9b 61 5f f3 14 28 78 2d 1d a6 39

CA机构COMODO SECURE的指纹为:

‎af e5 d2 44 a8 d1 19 42 30 ff 47 9f e2 f8 97 bb cd 7a 8c b4

下面我们看下Windows证书管理器中收录的CA证书和中间证书,单击开始-运行,输入certmgr.msc回车,单击菜单栏【操作】-【查找证书】, 输入COMODO,分别搜索“中间证书颁发机构”和“受信任的根证书颁发机构”,结果如下:

该证书的指纹为:

‎33 9c dd 57 cf d5 b1 41 16 9b 61 5f f3 14 28 78 2d 1d a6 39

该证书指纹为:

‎af e5 d2 44 a8 d1 19 42 30 ff 47 9f e2 f8 97 bb cd 7a 8c b4

由于在Windows上整条证书链的认证是完整的,所以在浏览器中可以成功验证证书的有效性。

我们再来看一下Java这边,Java拥有自己的keystore(通常位于$JAVA_HOME/lib/security/cacerts)用于存储CA证书和中间证书,双击$JAVA_HOME/bin/javacpl.exe打开Java控制台,单击【安全】- 【管理证书】,选择【系统】选项卡,然后单击证书类型下拉框查看相关证书。其实还有一种更简单的办法查看Java的信任证书列表,执行如下命令:

keytool -keystore "$JAVA_HOME\jre\lib\security\cacerts" -storepass changeit -list

该命令输出结果如下:

C:\Users\Lenovo>keytool -keystore "D:\Software\jdk1.8.0_111\jre\lib\security\cacerts" -storepass changeit -list

密钥库类型: JKS
密钥库提供方: SUN

您的密钥库包含 104 个条目

digicertassuredidrootca, 2008-4-16, trustedCertEntry,
证书指纹 (SHA1): 05:63:B8:63:0D:62:D7:5A:BB:C8:AB:1E:4B:DF:B5:A8:99:B2:4D:43
comodorsaca, 2015-5-12, trustedCertEntry,
证书指纹 (SHA1): AF:E5:D2:44:A8:D1:19:42:30:FF:47:9F:E2:F8:97:BB:CD:7A:8C:B4
thawtepremiumserverca, 2015-5-21, trustedCertEntry,
...
...

在上面的输出中,我们只能找到CA机构COMODO SECURE的指纹(上面的倒数第4行),而找不到中间证书COMODO RSA Domain Validation Secure Server CA的指纹,所以在Java中无法验证整条证书链的有效性,所以导致Java程序在通过HTTPS协议访问chatbot.cn域名时发生证书错误。通常的解决办法是在Http Client端设置忽略证书错误,或是将缺少的中间证书导入Java keystore,详情请Google之。

 

© 著作权归作者所有

共有 人打赏支持
joymufeng
粉丝 93
博文 72
码字总数 65080
作品 2
杨浦
高级程序员
私信 提问
HTTPS 和 Java 的融合问题

HTTPS 协议是一套完善的标准,它能确保网络连接的安全。要理解这套协议如何运作并非难事,而对应的 RFC 文档 早在 2000 年就有了。 尽管 HTTPS 的应用已经如此广泛,你仍然可以遇到一些软件并...

oschina
2016/11/01
3.3K
13
JA-SIG(CAS)学习笔记1

实验背景: 系统环境: Windows XP | SUN JDK1.6U4 | Tomcat6.0.14 | CAS Server 3.1.1 + CAS Client 2.1.1 主机完整名称: Linly 浏览器: FireFox V2.0.0.11 实验步骤: STEP 1,搭建Java ......

张xtpgyaps
2011/06/30
0
1
Tomcat在Linux上的安装与配置

Tomcat在Linux上的安装与配置 以下使用的Linux版本为: Redhat Enterprise Linux 7.0 x86_64,Tomcat版本为tomcat-7.0.54. 1.下载JDK与Tomcat. jdk下载地址: http://www.oracle.com/technetwo......

不忘初心77
2018/06/26
0
0
有谁可以讲解下https和ssl证书吗,

最近做的一个项目,用到各种证书,服务器证书,网关证书,和个人数字证书什么的,好复杂的样子, 12306的https和Google的https有什么不一样的 https://kyfw.12306.cn/otn/leftTicket/init, ...

yuyuyuyu
2014/12/10
242
3
解决 『SunCertPathBuilderException:unable to find valid certification path to requested target』 问题

版权声明:本文为 Abracadabra(爱博客大伯) 原创文章,转载请注明作者及链接,请勿用于任何商业用途。 https://blog.csdn.net/u013553529/article/details/82895226 解决 『SunCertPathBuil...

爱博客大伯
2018/09/29
0
0

没有更多内容

加载失败,请刷新页面

加载更多

发布xxl-job executor dotnet core 执行器的实现

DotXxlJob [github][https://github.com/xuanye/DotXxlJob] xxl-job的dotnet core 执行器实现,支持XXL-JOB 2.0+ 1 XXL-JOB概述 [XXL-JOB][1]是一个轻量级分布式任务调度平台,其核心设计目标...

假正经哥哥
今天
2
0
mysql 查询当天、本周,本月,上一个月的数据

今天 select * from 表名 where to_days(时间字段名) = to_days(now()); 昨天 SELECT * FROM 表名 WHERE TO_DAYS( NOW( ) ) - TO_DAYS( 时间字段名) <= 1 近7天 SELECT * FROM 表名 wher......

BraveLN
今天
3
0
Spring 事务初始化源码分析

相关文章 Spring 事务使用详解 Spring AOP 创建代理的源码解析 Spring AOP 注解方式源码解析 Spring AOP 功能使用详解 Spring 的 getBean 方法源码解析 Spring bean 创建过程源码解析 Spring...

TSMYK
今天
1
0
Android Multimedia框架总结(六)C++中MediaPlayer的C/S架构

前面几节中,都是通过java层调用到jni中,jni向下到c++层并未介绍 看下Java层一个方法在c++层 MediaPlayer后续过程 frameworks/av/media/libmedia/MediaPlayer.cpp 找一个我们之前熟悉的setDa...

天王盖地虎626
今天
3
0
【Linux】【MySQL】CentOS7安装最新版MySQL8.0.13(最新版MySQL从安装到运行)

1、前言   框框博客在线报时:2018-11-07 19:31:06   当前MySQL最新版本:8.0.13 (听说比5.7快2倍)   官方之前表示:MySQL 8.0 正式版 8.0.11 已发布,MySQL 8 要比 MySQL 5.7 快 2 ...

Code辉
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部