httpclient信任所有證書解決SSLException:Unrecognized SSL message,plaintext connection


在使用 HttpClient 工具調用第三方 Http 接口時報錯 javax.net.ssl.SSLException:Unrecognized SSL message,plaintext connection?

這個錯誤意思是說,無法識別 SSL 信息,明文連接?

看這個意思是說在使用 https 協議訪問網絡資源時無法識別 SSL 信息。

SSL(Secure Socket Layer 安全套接層)是基於HTTPS下的一個協議加密層,最初是由網景公司(Netscape)研發,后被IETF(The Internet Engineering Task Force - 互聯網工程任務組)標准化后寫入(RFCRequest For Comments 請求注釋),RFC里包含了很多互聯網技術的規范!

起初是因為HTTP在傳輸數據時使用的是明文(雖然說POST提交的數據時放在報體里看不到的,但是還是可以通過抓包工具竊取到)是不安全的,為了解決這一隱患網景公司推出了SSL安全套接字協議層,SSL是基於HTTP之下TCP之上的一個協議層,是基於HTTP標准並對TCP傳輸數據時進行加密,所以HPPTS是HTTP+SSL/TCP的簡稱。

SSL協議位於TCP/IP協議與各種應用層協議之間,為數據通訊提供安全支持。SSL協議可分為兩層: SSL記錄協議(SSL Record Protocol):它建立在可靠的傳輸協議(如TCP)之上,為高層協議提供數據封裝、壓縮、加密等基本功能的支持。 SSL握手協議(SSL Handshake Protocol):它建立在SSL記錄協議之上,用於在實際的數據傳輸開始前,通訊雙方進行身份認證、協商加密算法、交換加密密鑰等。

 本來 https 是在 http 的基礎上進行加密。使用 SSL 協議進行加密。

這樣通訊的雙方在通訊前就要去做身份校驗,通過證書的方式驗證身份。

原來是證書方面的問題,需要我們加一下代碼,使其信任所有證書。

如下代碼,設置信任所有代理。

import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.TrustStrategy;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

public class HttpClientUtil{
    
    public static CloseableHttpClient createSSLClientDefault() {
        try {
            //使用 loadTrustMaterial() 方法實現一個信任策略,信任所有證書
            SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
                // 信任所有
                public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                    return true;
                }
            }).build();
            //NoopHostnameVerifier類:  作為主機名驗證工具,實質上關閉了主機名驗證,它接受任何
            //有效的SSL會話並匹配到目標主機。
            HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
            return HttpClients.custom().setSSLSocketFactory(sslsf).build();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        }
        return HttpClients.createDefault();

    }
}

 

 獲取HttpClient 實例的方式由使用默認的 httpclient 變為我們自定義的 httpclient 實例

即,由

 

變為

這解決了我的問題。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM