我是如何解决java.security.cert.CertPathValidatorException异常的
问题来了
昨天,我还在我的工位上愉快的敲的代码,有位开发组的同事Z给我发消息。
开发组同事Z:大哥,这个PKI的登录功能是你做的吗?
我:是呀!N年前的事了。。。
开发组同事Z:PKI登录功能出问题了!有位客户使用他的PKI登录我们做的系统,登录时报错,换了几台电脑也不行。但是他使用他的PKI能登录其他的系统。能帮忙看一下吗,我找过好多同事看过了,他们看了下,都不知道如何入手
我:报错是报什么错?能具体的描述下吗?
开发组同事Z:访问系统时,能弹出证书的选择框,选择完证书后,Chrome浏览器的报错信息是:ERR_SSL_PROTOCOL_ERROR
我:行吧,我待会过去瞧瞧
问题分析
之前在配置tomcat的SSL时,我已经把客户证书的根证书已经导入到服务器信任证书列表内(配置见附录),“能弹出证书的选择框”说明服务器端是能识别出客户证书,但是为什么在登录的过程中,就报错了,可能有如下的几种原因:
- 服务器端的证书和服务器端的信任证书配置有误;(我一直以为是服务器端证书中的IP地址和服务器的IP不一致,后来才发现这个是不可能的)
- 登录过程中,tomcat能读取到客户端的证书,在程序处理的过程中,拒绝该证书;(客户端的证书的格式不被服务器端接受)
- 客户端证书过期了?(通过上面的描述好像不是这个错误)
- tomcat或者JDK有问题?(这个不太可能,其他用户使用PKI能登录呀)
解决问题
博主当时也是有点懵逼,不知道该怎么解决这个问题。好在博主有敢于尝试的精神,决定一个一个试一下。
重新安装服务器端证书
首先使用keytool
工具生成服务器端证书,再使用keytool
导入客户的根证书到服务器端的信任证书库中。然后把服务器端证书和服务器端的信任证书库放入tomcat,配置、重启tomcat(这里省略了具体的配置过程,具体的配置步骤见附录)。经过一番尝试,发现选择完证书还是报错。又经过一番折腾,还是没有找过是啥原因,正在灰心丧气的时候,灵机一动,程序员不是应该从日志中找错误吗?于是从网上找了一下java中如何开启SSL的日志信息。
日志带来曙光
在tomcat中加入JVM参数: -Djavax.net.debug=SSL,handshake,data,trustmanager
,重启tomcat。使用客户的证书重新登录,看到后台打印出了很多的日志信息,浏览了一遍后,发现了如下的异常:
http-nio-8443-exec-4, fatal error: 46: General SSLEngine problem
sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: algorithm constraints check failed
%% Invalidated: [Session-7, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256]
http-nio-8443-exec-4, SEND TLSv1.2 ALERT: fatal, description = certificate_unknown
http-nio-8443-exec-4, WRITE: TLSv1.2 Alert, length = 2
http-nio-8443-exec-4, fatal: engine already closed. Rethrowing javax.net.ssl.SSLHandshakeException: General SSLEngine problem
http-nio-8443-exec-4, called closeOutbound()
http-nio-8443-exec-4, closeOutboundInternal()
拿着这个异常信息java.security.cert.CertPathValidatorException: algorithm constraints check failed
去google上搜索了一下,找到了如下的这两个网站上的解决方法:
- https://stackoverflow.com/questions/21218217/ssl-handshake-exception-algorithm-constraints-check-failed-md5withrsa
- https://developer.ibm.com/answers/questions/366684/why-am-i-getting-algorithm-constraints-check-faile/
于是乎,按照上面的描述修改了JDK的配置信息,重启tomcat,使用证书登录,居然能正常登录了。心中暗自高兴了好一会儿,满满的成就感,想不到居然修改了一点配置就解决了......在高兴之余,想着搞清楚这到底是怎么一回事!接下来,容我慢慢道来。
刨根到底
到底是做了什么神奇的操作,就解决这问题了呢!首先找到JDK安装目录下的这个文件:
$JAVA_HOME/jre/lib/security/java.security
然后修改其中的两项配置(为了确保不出报错,把这两项禁用的算法全置为空):
# 处理证书路径时禁用的算法
jdk.certpath.disabledAlgorithms=
# 处理SSL/TLS时禁用的算法
jdk.tls.disabledAlgorithms=
然后重启tomcat就行了。
先看一下禁用的算法的语法,如下:
# 总体的语法
禁用的算法1, 禁用的算法2, 禁用的算法3...
# 禁用的每一项算法语法
算法名称 keySize 操作符 数值值
例如:DSA
表示禁用DSA算法,RSA keySize < 2048
表示禁用密钥长度小于2048的RSA算法,RSA keySize > 1024, RSA keySize < 2048
表示禁用密钥长度大于1024小于2048的RSA算法。
后来,仔细看了一下日志,发现在客户证书的信息有这么一行:
Signature Algorithm: SHA1withRSA, OID = 1.2.***.11***9.1.1.*
Key: Sun RSA public key, 1023 bits
客户证书的密钥长度居然是1023,而JDK8中为了安全性默认禁用了密钥长度小于2048的算法。最终修改的配置如下:
jdk.certpath.disabledAlgorithms=MD2, RSA keySize < 512
问题就这样解决了,哈哈!!!
总结
有时遇到问题,真的是让人摸不到头脑,这时别着急,把自己能想到的方法先尝试一遍,说不定就能行了呢。遇到问题首先可以借助日志来分析问题(就像上面那样打开JDK的SSL的调试日志的开关),通过日志大概就能定位到时哪里出问题了。在实际的开发中,很多程序猿基本上不会记录日志,稍微好一点的可能会在控制台使用System.out.println(xxxx)
输出日志,不习惯使用像log4j这样的日志框架来记录日志。有人会说,出了问题,我可以直接debug呀!你有没想过在生产环境中,你还能用IDE来进行调试吗?
附录
tomcat的SSL配置
编辑conf/server.xml文件加入如下的配置:
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
clientAuth="true" sslProtocol="TLS"
keystoreFile="${catalina.base}/server.ks" keystorePass="123456"
truststoreFile ="${catalina.base}/server_trust.ks"
truststorePass="123456"/>
说明:
- clientAuth为true表示开启SSL双向认证
- keystoreFile指定服务器端的证书位置
- truststoreFile指定服务器端信任证书库
服务器端证书配置
生成服务器端证书
keytool -genkeypair -v -alias server -keyalg RSA -validity 3650 -keystore ./server.ks -storepass 123456 -keypass 123456 -dname "CN=192.168.2.89,OU=zfx,O=zfx,L=gz,ST=gd,C=cn"
导出服务器端证书
keytool -exportcert -alias server -keystore ./server.ks -file ./server.cer -storepass 123456
导入服务器端证书到服务器信任证书列表
keytool -importcert -alias serverca -keystore ./server_trust.ks -file ./server.cer -storepass 123456
导入客户根证书到服务器信任证书列表
keytool -importcert -alias urootca -keystore ./server_trust.ks -file ./uroot.cer -storepass 123456
使用如下的命令查看信任的证书信息:
keytool -list -keystore ./server_trust.ks -storepass 123456
Keytool命令常用参数
- -genkeypair在用户主目录中创建一个默认文件”.keystore”,还会产生一个mykey的别名,mykey中包含用户的公钥、私钥和证书(在没有指定生成位置的情况下,keystore会存在用户系统默认目录)
- -alias 产生别名 每个keystore都关联这一个独一无二的alias,这个alias通常不区分大小写
- -keystore 指定密钥库的路径(产生的各类信息将不在.keystore文件中)
- -keyalg 指定密钥的算法 (如 RSA,DSA,默认值为:DSA)
- -validity 指定创建的证书有效期多少天(默认 90)
- -keysize 指定密钥长度 (默认 1024
- -storepass 指定密钥库的密码(获取keystore信息所需的密码)
- -keypass 指定别名条目的密码(私钥的密码)
- -dname 指定证书发行者信息 其中: “CN=名字与姓氏,OU=组织单位名称,O=组织名称,L=城市或区域名 称,ST=州或省份名称,C=单位的两字母国家代码”
- -list 显示密钥库中的证书信息如:keytool -list -v –keystore path/to/keystore -storepass password
- -v 显示密钥库中的证书详细信息
- -exportcert 导出指定别名的证书,如:keytool - exportcert -alias theAlias -keystore path/to/keystore -file path/to/keystore/cert -storepass pass
- -file 参数指定导出到文件的文件名
- -delete 删除密钥库中某条目 keytool -delete -alias theAlias -keystore path/to/keystore –storepass pass
- -printcert 控制台打印证书的详细信息,如:keytool -printcert -file path/to/keystore/cert -v
- -keypasswd 修改密钥库中指定条目口令 keytool -keypasswd -alias theAlias -keypass oldPass -new newPass -storepass keystorePass -keystore path/to/keystore
- -storepasswd 修改keystore口令 keytool -storepasswd -keystore path/to/keystore -storepass oldPass -new newPass
- -importcert 将已签名数字证书导入密钥库 keytool -importcert -alias certAlias -keystore path/to/keystore -file path/to/keystore/cert
我是如何解决java.security.cert.CertPathValidatorException异常的的更多相关文章
- andorid HTTPS 不需要证书 VolleyEror: com.android.volley.NoConnectionError: javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not fou
1.加证书(这里不说) 2.修改代码 import java.security.KeyManagementException;import java.security.NoSuchAlgorithmE ...
- Java_解决java.security.cert.CertificateException: Certificates does not conform to algorithm constraints
找到 jre/lib/security/java.security 将 jdk.certpath.disabledAlgorithms=MD2, DSA, RSA keySize < 2048 ...
- 解决 java.security.cert.CertificateException: java.lang.IllegalArgumentException: Invalid input to toASCII:
使用 okhttp3 ,请求 一个 https 网站报错 , 类似这种 https://test_test.test.com , 百度不到问题 所以我写了这篇 给中文世界贡献一下如何解决 还是要学好英 ...
- 在ssm框架测试中解决javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException
在单元测试发现causeBy:javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException 经发现是db.p ...
- JAVA 调用https接口, java.security.cert.CertificateException
package com.easycare.store.util; import java.security.cert.CertificateException; import java.securit ...
- 终极解决方案:java.security.cert.CertificateException: Certificates does not conform to algorithm constraints
报错信息 javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: Certificates does ...
- java.security.cert.CertificateException: No subject alternative names matching IP address xxx.xxx.xxx.xxx found
https与http不同的是,https加密,需要验证证书,而http不需要. 在连接的代码中加上: static { disableSslVerification(); } private stat ...
- java.security.cert.CertificateException: No subject alternative names present
背景:在开发一个项目中,要调用一个webservice服务,之前设置的是http协议,项目中采用jdk自带的wsimport工具生成的客户端代码; 后来,需求变更要求兼容https协议的webserv ...
- 解決 java.security.cert.CertificateException: Certificates does not conform to algorithm constraints
找到 jre/lib/security/java.security 将 jdk.certpath.disabledAlgorithms=MD2, DSA, RSA keySize < 2048 ...
随机推荐
- tcp/ip 三次握手和4次挥手
TCP连接两个端口,谁也发起请求,谁就是client端A,另外一个接受请求的server端B.第一次握手:A向B发一个链接请求,带一个seq = x,SYN= x. 第二次握手:B收到链接请求之后向A ...
- Linux 比较判断运算(if else)
200 ? "200px" : this.width)!important;} --> 介绍 本篇文章主要是列举在shell命令中常出现的一些用来做比较的运算符,这些运算符是 ...
- Java编程实现多线程TCP服务器完整实例
Socket ·功能:TCP客户端套接字 ·构造方法: Socket(InetAddress address, int port) 创建一个流套接字并将其连接到指定 IP 地址的指定端口号 · ...
- Jquery+Eayui实现列表选择功能
在做一个列表选择的功能,要实现一个Jquery列表选择器的效果,如图就是很常见的一种列表选择器 不过网上开源的可能要积分,资料没找到合适的,所以自己就简单写了一下,其实实现也不是很难.实现思路:左边双 ...
- Python的 is 和 == 弄懂了吗?
在Python中一切都是对象. Python中对象包含的三个基本要素,分别是: id(身份标识) type(数据类型) value(值) 对象之间比较是否相等可以用 == ,也可以用 is . is ...
- 在Mac上安装MongoDB,配置全局路径
1.访问MongoDB官方下载地址 http://www.mongodb.org/downloads 2.点击“DOWNLOAD(tgz)”按钮: 3.将下载的文件压缩包解压后剪切到你的Mac中某个位 ...
- 深入Vue2.x的虚拟DOM diff原理
一.前言 Vue的核心是双向绑定和虚拟DOM(下文我们简称为vdom),关于双向绑定可以参阅木琴的文章<剖析Vue原理&实现双向绑定MVVM>,vdom是树状结构,其节点为vnod ...
- html标签详解(2)
http标签详解 声明 1:这里的文字都是我从我自己csdn账号拷贝过来,是本人学习总结的结晶,所以请尊重本作品.2:如要要转载本文章,则要说明文字的出处.3:如有哪里不对欢迎指出. 在上一篇文章中主 ...
- 课程回顾-Convolutional Neural Networks
为什么卷积层计算量更低paddingStrided convolution多维卷积LeNet 参数卷积网络的好处参数共享稀疏连接经典网络实现LeNet-5AlexNetVGGResNet残差块iden ...
- mysql 开发基础系列10 存储引擎 InnoDB 介绍
一. 概述: InnoDB存储引擎提供了具有提交,回滚,和崩溃恢复能力的事务安全,对比MYISAM 的存储引擎,InnoDB写的处理效率差一些并且会占用更多的磁盘空间以保留数据和索引.它的特点有如下: ...