Java在请求某些不受信任的https网站时会报:PKIX path building failed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
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(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.java:
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.startHandshake(SSLSocketImpl.java:
1339
)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:
1323
)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:
563
)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:
185
)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:
1300
)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:
254
)
at SslTest.getRequest(SslTest.java:
16
)
at SslTest.main(SslTest.java:
40
)
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:
385
)
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:
230
)
at sun.security.validator.Validator.validate(Validator.java:
260
)
at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:
326
)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:
231
)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:
126
)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:
1323
)
...
13
more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:
196
)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:
268
)
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:
380
)
...
19
more
|
解决办法:
1、导入证书到本地证书库
2、信任所有SSL证书
最好的解决办法或许是信任所有SSL证书,因为某些时候不能每次都手动的导入证书非常麻烦。现在封装了个方法,在连接openConnection的时候忽略掉证书就行了。
1
|
SslUtils.ignoreSsl();
|
SslUtils.java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
import
java.security.cert.CertificateException;
import
java.security.cert.X509Certificate;
import
javax.net.ssl.HostnameVerifier;
import
javax.net.ssl.HttpsURLConnection;
import
javax.net.ssl.SSLContext;
import
javax.net.ssl.SSLSession;
import
javax.net.ssl.TrustManager;
import
javax.net.ssl.X509TrustManager;
public
class
SslUtils {
private
static
void
trustAllHttpsCertificates()
throws
Exception {
TrustManager[] trustAllCerts =
new
TrustManager[
1
];
TrustManager tm =
new
miTM();
trustAllCerts[
0
] = tm;
SSLContext sc = SSLContext.getInstance(
"SSL"
);
sc.init(
null
, trustAllCerts,
null
);
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
}
static
class
miTM
implements
TrustManager,X509TrustManager {
public
X509Certificate[] getAcceptedIssuers() {
return
null
;
}
public
boolean
isServerTrusted(X509Certificate[] certs) {
return
true
;
}
public
boolean
isClientTrusted(X509Certificate[] certs) {
return
true
;
}
public
void
checkServerTrusted(X509Certificate[] certs, String authType)
throws
CertificateException {
return
;
}
public
void
checkClientTrusted(X509Certificate[] certs, String authType)
throws
CertificateException {
return
;
}
}
/**
* 忽略HTTPS请求的SSL证书,必须在openConnection之前调用
* @throws Exception
*/
public
static
void
ignoreSsl()
throws
Exception{
HostnameVerifier hv =
new
HostnameVerifier() {
public
boolean
verify(String urlHostName, SSLSession session) {
System.out.println(
"Warning: URL Host: "
+ urlHostName +
" vs. "
+ session.getPeerHost());
return
true
;
}
};
trustAllHttpsCertificates();
HttpsURLConnection.setDefaultHostnameVerifier(hv);
}
}
|
SslTest.java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
import
java.io.OutputStreamWriter;
import
java.net.URL;
import
java.net.URLConnection;
import
org.apache.commons.io.IOUtils;
public
class
SslTest {
public
String getRequest(String url,
int
timeOut)
throws
Exception{
URL u =
new
URL(url);
if
(
"https"
.equalsIgnoreCase(u.getProtocol())){
SslUtils.ignoreSsl();
}
URLConnection conn = u.openConnection();
conn.setConnectTimeout(timeOut);
conn.setReadTimeout(timeOut);
return
IOUtils.toString(conn.getInputStream());
}
public
String postRequest(String urlAddress,String args,
int
timeOut)
throws
Exception{
URL url =
new
URL(urlAddress);
if
(
"https"
.equalsIgnoreCase(url.getProtocol())){
SslUtils.ignoreSsl();
}
URLConnection u = url.openConnection();
u.setDoInput(
true
);
u.setDoOutput(
true
);
u.setConnectTimeout(timeOut);
u.setReadTimeout(timeOut);
OutputStreamWriter osw =
new
OutputStreamWriter(u.getOutputStream(),
"UTF-8"
);
osw.write(args);
osw.flush();
osw.close();
u.getOutputStream();
return
IOUtils.toString(u.getInputStream());
}
public
static
void
main(String[] args) {
try
{
SslTest st =
new
SslTest();
String a = st.getRequest(
"https://xxx.com/login.action"
,
3000
);
System.out.println(a);
}
catch
(Exception e) {
e.printStackTrace();
}
}
}
|
阅读全文……