【问题标题】:javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException [duplicate]javax.net.ssl.SSLHandshakeException:java.security.cert.CertificateException [重复]
【发布时间】:2013-10-05 03:59:42
【问题描述】:

我写了下面的代码。已成功导入证书。谁能告诉我获得异常的原因可能是什么?我正在尝试连接一个 IP https://x.x.x.x 但出现异常。我尝试了两件事

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());

    }

}

【问题讨论】:

  • 你能显示完整的异常吗?它应该指出证书有什么问题。
  • 线程“主”javax.net.ssl.SSLHandshakeException 中的异常:java.security.cert.CertificateException:在 sun.security.ssl.Alerts.getSSLException(未知来源)处没有主题替代名称sun.security.ssl.SSLSocketImpl.fatal(Unknown Source) 在 sun.security.ssl.Handshaker.fatalSE(Unknown Source) 在 sun.security.ssl.Handshaker.fatalSE(Unknown Source) 在 sun.security.ssl.ClientHandshaker。 serverCertificate(Unknown Source) at sun.security.ssl.ClientHandshaker.processMessage(Unknown Source) at sun.security.ssl.Handshaker.processLoop(Unknown Source)
  • 引起:java.security.cert.CertificateException:sun.security.util.HostnameChecker.matchIP(未知来源)中没有主题替代名称
  • 请注意,您使用的 TrustManager 根本不安全。不要将其部署为生产代码。

标签: java ssl ssl-certificate


【解决方案1】:

这与this question 中的问题完全相同。默认的 Java 主机名验证器在处理 IP 地址时严格实现 RFC 2818

在某些情况下,URI 被指定为 IP 地址而不是主机名。在这种情况下,iPAddress subjectAltName 必须出现在证书中,并且必须与 URI 中的 IP 完全匹配。

特别是,当在 SAN 中找不到 IP 地址时,它不会回退到主题 DN 中的 CN。

基本上,该服务的证书不符合 HTTPS 规范(但有些浏览器无论如何都会接受它)。

您应该与控制该服务器的人取得联系,并要求他们为该 IP 地址放置一个带有 SAN 条目的证书(注意条目的类型必须是“IP 地址”,而不是“DNS”) .

【讨论】:

    猜你喜欢
    • 2016-05-07
    • 2014-04-23
    • 2020-04-17
    • 1970-01-01
    • 2012-06-22
    • 2016-07-08
    • 2020-06-14
    • 2014-09-14
    • 2015-06-20
    相关资源
    最近更新 更多