如何处理最终导致纯文本连接的https url

2022-09-04 20:21:14

我尝试获取https url的页面内容,该URL在获取输入流时引发异常。

String httpsURL = "https://careers.virtusa.com/";
URL myurl = new URL(httpsURL);
HttpsURLConnection con = (HttpsURLConnection)myurl.openConnection();
InputStream ins = con.getInputStream();

例外情况如下:

Exception in thread "main" javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?
    at com.sun.net.ssl.internal.ssl.InputRecord.handleUnknownRecord(InputRecord.java:523)
    at com.sun.net.ssl.internal.ssl.InputRecord.read(InputRecord.java:355)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:798)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1138)    
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1165)    
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1149)    
    at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:434)    
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:166)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1172)    
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:234)      
    at url.JavaHttpsExample.main(JavaHttpsExample.java:18)    

两者兼而有之,并失败。我试过了,但得到了同样的例外。在浏览器中,它工作正常。HttpURLConnectionHttpsURLConnectionorg.apache.http.impl.client.CloseableHttpClient


答案 1

指定 careers.virtusa.com 正在使用的 SSL 版本。即 在代码中。TLSv1.2

SSLContext sc = SSLContext.getInstance(“TLSv1.2”);

public String getData(String URL)
{
    TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return null;
        }

        public void checkClientTrusted(X509Certificate[] certs,
                String authType) {
        }

        public void checkServerTrusted(X509Certificate[] certs,
                String authType) {
        }

    } };

    String output = "";
    try{

        //System.setProperty("https.proxyHost", "<PROXY HOST IP>");   // Uncomment if using proxy
        //System.setProperty("https.proxyPort", "<PROXY HOST PORT>");        // Uncomment if using proxy
        SSLContext sc = SSLContext.getInstance("TLSv1.2");
        sc.init(null, trustAllCerts, new java.security.SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

        // Create all-trusting host name verifier
        HostnameVerifier allHostsValid = new HostnameVerifier() {
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        };
        // Install the all-trusting host verifier
        HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
        /*
         * end of the fix
         */

        URL url = new URL(URL);
        URLConnection con = url.openConnection();

        InputStream ins = con.getInputStream();
        InputStreamReader isr = new InputStreamReader(ins);
        BufferedReader in = new BufferedReader(isr);

        String inputLine;


        while ((inputLine = in.readLine()) != null) {
            output = output + inputLine;
        }

        System.out.println(output);
        in.close();

    }   
    catch(Exception e){
        e.printStackTrace();            
    }


    return output;
}

答案 2

我没有得到你得到的错误。我还验证了您尝试梳理的网站实际上是针对HTTPS配置的。这是我得到的例外:plaintext connection

java.security.cert.CertificateException:找不到匹配 sub.website.com 使用者替代 DNS 名称。

此问题的一个解决方案是安装一个信任所有主机(包括 )的主机验证程序。尝试使用以下代码段,它将您的目标页面输出到 Java 控制台:sun.website.com

HostnameVerifier allHostsValid = new HostnameVerifier() {
    public boolean verify(String hostname, SSLSession session) {
        return true;
    }
};

HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);

String httpsURL = "https://sub.website.com/";
URL myurl = new URL(httpsURL);
HttpsURLConnection con = (HttpsURLConnection)myurl.openConnection();

BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream()));
String input;
while ((input = br.readLine()) != null) {
    System.out.println(input);
}
br.close();

注意:

当OP使用不同的网站时,我给出了这个答案。答案对于给出的条件是有效的,尽管OP可能从那时起发生了变化。