[已解决]java请求爬取https网站报错javax.net.ssl.SSLHandshakeException的解决办法

前言

在爬取https网站的时候,今天遇到了一个之前没有见过的异常javax.net.ssl.SSLHandshakeException,具体细节请看如图

2020-06-01 23:18:17.032 DEBUG org.springframework.web.servlet.DispatcherServlet
- Successfully completed request
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException:
PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderExce
ption: unable to find valid certification path to requested target
        at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
        at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1884)
        at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:276)
        at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:270)
        at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.
java:1341)
        at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.jav
a:153)
        at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868)
        at sun.security.ssl.Handshaker.process_record(Handshaker.java:804)
        at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1016)
        at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.
java:1312)
        at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:702)
        at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:122)
        at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82
)
        at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
        at org.apache.commons.httpclient.HttpConnection.flushRequestOutputStream
(HttpConnection.java:828)
        at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodB
ase.java:2116)
        at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.j
ava:1096)
        at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(Htt
pMethodDirector.java:398)
        at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMe
thodDirector.java:171)
        at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.jav
a:397)

产生原因是jdk的证书库里并没有将该站点的证书作为受信任的安全证书。

解决方法是导该站点的证书,将此证书导入到java的信任证书库中。

注意事项:

要注意的是,在win7或更高的系统中,运行一定要以管理员身份运行CMD,Mac os 要用sudo -i 命令切换为 root用户,否则会报以下错

keytool错误: java.io.FileNotFoundException:   

操作步骤:

把证书导入java的cacerts证书库的步骤:

第一步:用浏览器打开网站,把要导入java证书库的证书下载
        在该网页安全警报弹出窗口上查看证书--详细信息--复制到文件
        会弹出一个证书导出向导对话框,按提示一直下一步直到完成。
        我把证书保存在C盘,名字为NEXT_CertKey.cer 或是 xxxx.der。

第二步:将上面导出的证书导入java中的cacerts证书库
        windows  cmd进入D:\Program Files\Java\jdk1.7.0_67\bin 目录

  (这里要找到你们的jdk安装目录)


        敲入如下命令回车执行
        keytool -import -alias cacerts -keystore  D:\Program Files\Java\jdk1.7.0_67\jre\lib\security\cacerts -file C:\NEXT_CertKey.cer -trustcacerts
        此时命令行会提示你输入cacerts证书库密码,
        java中cacerts证书库默认密码为changeit,
        Y确认即可,OK,认证已添加至keystore。

我在本地测试的时候,用上面的好像有点问题,但是用下面的是可以的,大家可以两种方法都试一下,看下哪种可以导入进去

keytool -import -keystore "%JAVA_HOME%\jre\lib\security\cacerts" -file D:/jxust_CertKey.cer -alias ssodemo 

演示效果如图所示 

 mac os 终端进入 /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/lib/security

sudo keytool -import -alias cacerts -keystore /Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home/jre/lib/security/cacerts -file /Users/xuwenfeng/Desktop/RuckusWirelessZoneDirectorSN-491508001359 -trustcacerts


参考文章 

https://www.iteye.com/blog/bewithme-2227487

感谢原作者的分享,让技术人能够更快的解决问题 

猜你喜欢

转载自blog.csdn.net/qq_27471405/article/details/106485866