httpclient向HTTPS發送資料建立SSL串連時的異常

來源:互聯網
上載者:User
異常資訊如下:

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

原因:伺服器的認證不被信任。一般是這樣造成的。

使用KEYTOOL工具建立認證,然後用TOMCAT啟動後,在瀏覽器開啟網站時,會出現認證不被信任的提示。當然,利用HTTPCLIENT向服務端HTTPS發送資料時,HTTPCLIENT也會檢測服務端的認證是否被信任,不被信任就拋出上面的異常。

解決辦法有兩種,一種是使認證被用戶端信任。另一種是使用HTTPCLIENT發送資料時不檢測伺服器憑證是否可信。

第一種辦法,使認證被信任。

找正規CA簽發認證,或者自己簽發認證(只能那一台客戶機上可信)。找正規CA簽發認證就不說了,自己簽發認證呢,見我的其他文章。

我發現,自己簽名的認證弄好之後,從用戶端開啟服務端地址時,不再提示上面的錯誤,但是還是不能發送資料。原因是什麼呢?因為那台認證在用戶端作業系統上可信,但是在JAVA的KEYSTORE裡不可信,要把服務端的認證匯入KEYSTORE庫中

匯入辦法:

開啟命令列視窗,併到<java-home>\lib\security\ 目錄下,運行下面的命令:

keytool -import -noprompt -keystore cacerts -storepass changeit -alias yourEntry1 -file your.cer

最後一個是服務端匯出的認證,其他可以預設。

要注意的是,如果用戶端電腦上裝有許多個JAVA版本,要確定你匯入的認證的JAVA版本是你TOMCAT使用的那個,一般TOMCAT使用的是環境變數指向的那個JAVA版本。

如果是在ECLIPSE中建立的TOMCAT伺服器,建立時會要你選擇預設JRE還是指向的JAVA,這裡一定要選指向剛才匯入的那個JAVA的路徑,不然,你匯入的認證庫也沒效果。

第二種辦法,使用HTTPCLIENT時不檢測伺服器憑證是否可信

擴充HttpClient 類實現自動接受認證

因為這種方法自動接收所有認證,因此存在一定的安全問題,所以在使用這種方法前請仔細考慮您的系統的安全需求。具體的步驟如下:

•提供一個自訂的socket factory (test.MySecureProtocolSocketFactory )。這個自訂的類必須實現介面org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory ,在實現介面的類中調用自訂的X509TrustManager(test.MyX509TrustManager) ,這兩個類可以在隨本文帶的附件中得到

•建立一個org.apache.commons.httpclient.protocol.Protocol 的執行個體,指定協議名稱和預設的連接埠號碼

Protocol myhttps = new Protocol("https", new MySecureProtocolSocketFactory (), 443);

•註冊剛才建立的https 協議對象

Protocol.registerProtocol("https ", myhttps);

•然後按照普通編程 方式開啟https 的目標地址,代碼如下:

MySecureProtocolSocketFactory.java

import java.io.IOException;      import java.net.InetAddress;      import java.net.InetSocketAddress;      import java.net.Socket;      import java.net.SocketAddress;      import java.net.UnknownHostException;      import java.security.KeyManagementException;      import java.security.NoSuchAlgorithmException;      import java.security.cert.CertificateException;      import java.security.cert.X509Certificate;            import javax.net.SocketFactory;      import javax.net.ssl.SSLContext;      import javax.net.ssl.TrustManager;      import javax.net.ssl.X509TrustManager;            import org.apache.commons.httpclient.ConnectTimeoutException;      import org.apache.commons.httpclient.params.HttpConnectionParams;      import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;            public class MySecureProtocolSocketFactory implements SecureProtocolSocketFactory {          private SSLContext sslcontext = null;                    private SSLContext createSSLContext() {              SSLContext sslcontext=null;              try {                  sslcontext = SSLContext.getInstance("SSL");                  sslcontext.init(null, new TrustManager[]{new TrustAnyTrustManager()}, new java.security.SecureRandom());              } catch (NoSuchAlgorithmException e) {                  e.printStackTrace();              } catch (KeyManagementException e) {                  e.printStackTrace();              }              return sslcontext;          }                    private SSLContext getSSLContext() {              if (this.sslcontext == null) {                  this.sslcontext = createSSLContext();              }              return this.sslcontext;          }                    public Socket createSocket(Socket socket, String host, int port, boolean autoClose)                  throws IOException, UnknownHostException {              return getSSLContext().getSocketFactory().createSocket(                      socket,                      host,                      port,                      autoClose                  );          }                public Socket createSocket(String host, int port) throws IOException,                  UnknownHostException {              return getSSLContext().getSocketFactory().createSocket(                      host,                      port                  );          }                              public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort)                  throws IOException, UnknownHostException {              return getSSLContext().getSocketFactory().createSocket(host, port, clientHost, clientPort);          }                public Socket createSocket(String host, int port, InetAddress localAddress,                  int localPort, HttpConnectionParams params) throws IOException,                  UnknownHostException, ConnectTimeoutException {              if (params == null) {                  throw new IllegalArgumentException("Parameters may not be null");              }              int timeout = params.getConnectionTimeout();              SocketFactory socketfactory = getSSLContext().getSocketFactory();              if (timeout == 0) {                  return socketfactory.createSocket(host, port, localAddress, localPort);              } else {                  Socket socket = socketfactory.createSocket();                  SocketAddress localaddr = new InetSocketAddress(localAddress, localPort);                  SocketAddress remoteaddr = new InetSocketAddress(host, port);                  socket.bind(localaddr);                  socket.connect(remoteaddr, timeout);                  return socket;              }          }                    //自訂私人類          private static class TrustAnyTrustManager implements X509TrustManager {                           public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {              }                       public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {              }                       public X509Certificate[] getAcceptedIssuers() {                  return new X509Certificate[]{};              }          }                      }
  • 相關文章

    聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.