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 sun.security.ssl.Alerts.getSSLException(Unknown Source) at sun.security.ssl.SSLSocketImpl.fatal(Unknown Source) at sun.security.ssl.Handshaker.fatalSE(Unknown Source) at sun.security.ssl.Handshaker.fatalSE(Unknown Source) at sun.security.ssl.ClientHandshaker.serverCertificate(Unknown Source) at sun.security.ssl.ClientHandshaker.processMessage(Unknown Source) at sun.security.ssl.Handshaker.processLoop(Unknown Source) at sun.security.ssl.Handshaker.process_record(Unknown Source) at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source) at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source) at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source) at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source) at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:394) at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:353) at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:134) at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:353) at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:380) at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236) at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184) at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88) at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110) at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184) at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82) at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:107) 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(Unknown Source) at sun.security.validator.PKIXValidator.engineValidate(Unknown Source) at sun.security.validator.Validator.validate(Unknown Source) at sun.security.ssl.X509TrustManagerImpl.validate(Unknown Source) at sun.security.ssl.X509TrustManagerImpl.checkTrusted(Unknown Source) at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source) ... 24 more Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(Unknown Source) at java.security.cert.CertPathBuilder.build(Unknown Source) ... 30 more
从报错大概知道,是认证问题,证书没找到。 找了个简单类SSLPoke.class,访问该URL,问题依旧。 加上debug参数,如: "D:\xxx\jre64\bin\java" -Djavax.net.debug=all SSLPoke baidu.com 443 >xx.txt 可以得到详细的握手交互过程。
------------------------------------ 在正常机器上,是这样的。 chain [0] = [ [ Issuer: CN=GeoTrust CN RSA CA G1, OU=www.digicert.com, O=DigiCert Inc, C=US
chain [1] = [ [ Issuer: CN=DigiCert Global Root CA, OU=www.digicert.com, O=DigiCert Inc, C=US
DigiCert的根证书是系统内置的,所以验证没有问题。 ---------------------------
在问题机器上,可以看到认证链只有一个,证书的Subject是正确的,但是Issuer是GlobalSignature Certificates CA 2。
*** Certificate chain chain [0] = [ Issuer: CN=GlobalSignature Certificates CA 2, C=EN 这个根证书,jdk的证书库里是没有的,所以认证失败。 main, SEND TLSv1 ALERT: fatal, description = certificate_unknown ---------------------------
怀疑是服务端下发的证书不正确。
在ClientHello阶段,客户端支持 Extension server_name, server_name: [host_name: xxx.com] 所以这点没有问题。
使用SSL测试网站,测试也没有问题,证书是OK的。
在服务端抓包,然后在问题机器上访问,发现服务端下发证书是正确的,证书链是两个,颁发者正确。 但问题机收到的证书颁发者不正确,所以是中途或被问题机器上某些软件替换的。 问题机没装什么软件,所以可能是网络设备替换的。
具体没有继续查。
解决办法: (1)修改java代码,访问url时不检查证书,具体baidu吧 (2)将系统里的GlobalSignature Certificates CA 2证书导出,导入到jdk的证书库里。 凑合吧。
查看系统的证书,执行certmgr.msc即可,右键左侧树可以搜索。
|