javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19074740/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException
提问by amiton2006
I have written below code. Have imported the certificate successfully. Can anyone tell me what may be the reason for getting the exception? I am trying to connect one IP https://x.x.x.xbut getting the exception. I tried two things
我写了下面的代码。已成功导入证书。谁能告诉我获得异常的原因是什么?我正在尝试连接一个 IP https://xxxx,但出现异常。我尝试了两件事
1) By passing the certificate 2) Download the certificate and add it into the java trust store using keytool. For me none is working fine.
1) 通过传递证书 2) 下载证书并使用 keytool 将其添加到 java 信任库中。对我来说,没有一个工作正常。
package com.dell;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.GeneralSecurityException;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
public class HttpURLConnectionExample {
private final String USER_AGENT = "Mozilla/5.0";
public static void main(String[] args) throws Exception {
HttpURLConnectionExample http = new HttpURLConnectionExample();
System.out.println("Testing 1 - Send Http GET request");
http.sendGet();
System.out.println("\nTesting 2 - Send Http POST request");
http.sendPost();
}
// HTTP GET request
private void sendGet() throws Exception {
URL obj = null;
TrustManager[] trustAllCerts = new TrustManager[] {
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
}
};
// Install the all-trusting trust manager
try {
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection
.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (GeneralSecurityException e) {
}
try {
obj = new URL("https://10.94.218.114");
} catch (MalformedURLException e) {
}
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
con.setRequestProperty("User-Agent", USER_AGENT);
int responseCode = con.getResponseCode();
System.out.println("Response Code : " + responseCode);
BufferedReader in = new BufferedReader( new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
//print result
System.out.println(response.toString());
}
// HTTP POST request
private void sendPost() throws Exception {
String url = "https://selfsolve.apple.com/wcResults.do";
URL obj = new URL(url);
HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();
//add request header
con.setRequestMethod("POST");
con.setRequestProperty("User-Agent", USER_AGENT);
con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
String urlParameters = "sn=C02G8416DRJM&cn=&locale=&caller=&num=12345";
// Send post request
con.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(urlParameters);
wr.flush();
wr.close();
int responseCode = con.getResponseCode();
System.out.println("\nSending 'POST' request to URL : " + url);
System.out.println("Post parameters : " + urlParameters);
System.out.println("Response Code : " + responseCode);
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
System.out.println(response.toString());
}
}
采纳答案by Bruno
This is exactly the same problem as in this question. The default Java host name verifier implements RFC 2818strictly when it deals with IP addresses:
这与此问题中的问题完全相同。默认的 Java 主机名验证器在处理 IP 地址时严格执行RFC 2818:
In some cases, the URI is specified as an IP address rather than a hostname. In this case, the iPAddress subjectAltName must be present in the certificate and must exactly match the IP in the URI.
在某些情况下,URI 被指定为 IP 地址而不是主机名。在这种情况下,iPAddress subjectAltName 必须存在于证书中,并且必须与 URI 中的 IP 完全匹配。
In particular, it doesn't fall back on the CN in the Subject DN when the IP address isn't found in the SAN.
特别是,当在 SAN 中找不到 IP 地址时,它不会回退到主题 DN 中的 CN。
Essentially, the certificate for that service is not compliant with the HTTPS specification (but some browsers will accept it anyway).
本质上,该服务的证书不符合 HTTPS 规范(但某些浏览器无论如何都会接受)。
You should get in touch with whoever controls that server and ask them to put in place a certificate with a SAN entry for this IP address (note that the type of entry needs to be "IP address", not "DNS").
您应该与控制该服务器的人取得联系,并要求他们为该 IP 地址设置带有 SAN 条目的证书(请注意,条目类型必须是“IP 地址”,而不是“DNS”)。