HttpClient自定義SSL上下文


使用安全通訊端層,可以在用戶端和伺服器之間建立安全連線。它有助於保護敏感資訊,如信用卡號,使用者名,密碼,別針等。

可以使用HttpClient庫建立自己的SSL上下文,從而使連線更安全。按照下面給出的步驟使用HttpClient庫自定義SSLContext -

第1步 - 建立SSLContextBuilder物件
SSLContextBuilderSSLContext物件的構建器。使用SSLContexts類的custom()方法建立物件。

//Creating SSLContextBuilder object
SSLContextBuilder SSLBuilder = SSLContexts.custom();

第2步 - 載入金鑰庫
在路徑Java_home_directory/jre/lib/security/中,可以找到名為cacerts的檔案。將其儲存為金鑰庫檔案(擴充套件名為.jks)。使用SSLContextBuilder類的loadTrustMaterial()方法載入金鑰庫檔案及其密碼(預設為changeit)。

//Loading the Keystore file
File file = new File("mykeystore.jks");
SSLBuilder = SSLBuilder.loadTrustMaterial(file, "changeit".toCharArray());

第3步 - 構建SSLContext物件
SSLContext物件表示安全通訊端協定實現。使用build()方法構建SSLContext

//Building the SSLContext
SSLContext sslContext = SSLBuilder.build();

第4步 - 建立SSLConnectionSocketFactory物件

SSLConnectionSocketFactory是用於TSL和SSL連線的分層通訊端工廠。使用此方法,可以使用受信任證書列表驗證https伺服器並驗證給定的https伺服器。

可以通過多種方式建立它。根據建立SSLConnectionSocketFactory物件的方式可允許所有主機,僅允許自簽名證書,僅允許特定協定等。

要僅允許特定協定,請通過傳遞SSLContext物件,表示需要支援的協定的字串陣列,表示需要支援的密碼套件的字串陣列以及表示其建構函式的HostnameVerifier物件來建立SSLConnectionSocketFactory物件。

new SSLConnectionSocketFactory(sslcontext, new String[]{"TLSv1"}, null,    
   SSLConnectionSocketFactory.getDefaultHostnameVerifier());

要允許所有主機,請通過傳遞SSLContext物件和NoopHostnameVerifier物件來建立SSLConnectionSocketFactory物件。

//Creating SSLConnectionSocketFactory SSLConnectionSocketFactory object
SSLConnectionSocketFactory sslConSocFactory = new SSLConnectionSocketFactory(sslcontext, new NoopHostnameVerifier());

第5步 - 建立一個HttpClientBuilder物件
使用HttpClients類的custom()方法建立HttpClientBuilder物件。

//Creating HttpClientBuilder
HttpClientBuilder clientbuilder = HttpClients.custom();

第6步 - 設定SSLConnectionSocketFactory物件
使用setSSLSocketFactory()方法將SSLConnectionSocketFactory物件設定為HttpClientBuilder

//Setting the SSLConnectionSocketFactory
clientbuilder = clientbuilder.setSSLSocketFactory(sslConSocFactory);

第7步 - 構建CloseableHttpClient物件
通過呼叫build()方法構建CloseableHttpClient物件。

//Building the CloseableHttpClient
CloseableHttpClient httpclient = clientbuilder.build();

第8步 - 建立一個HttpGet物件
HttpGet類表示HTTP GET請求,該請求使用URI檢索給定伺服器的資訊。

通過傳遞表示URI的字串來範例化HttpGet類來建立HTTP GET請求。

//Creating the HttpGet request
HttpGet httpget = new HttpGet("https://www.tw511.com/");

第9步 - 執行請求
使用execute()方法執行請求。

//Executing the request
HttpResponse httpresponse = httpclient.execute(httpget);

範例

以下範例演示了SSLContrext的自定義 -

import java.io.File;
import javax.net.ssl.SSLContext;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
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.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;

public class ClientCustomSSL {

   public final static void main(String[] args) throws Exception {

      //Creating SSLContextBuilder object
      SSLContextBuilder SSLBuilder = SSLContexts.custom();

      //Loading the Keystore file
      File file = new File("mykeystore.jks");
      SSLBuilder = SSLBuilder.loadTrustMaterial(file,
         "changeit".toCharArray());

      //Building the SSLContext usiong the build() method
      SSLContext sslcontext = SSLBuilder.build();

      //Creating SSLConnectionSocketFactory object
      SSLConnectionSocketFactory sslConSocFactory = new SSLConnectionSocketFactory(sslcontext, new NoopHostnameVerifier());

      //Creating HttpClientBuilder
      HttpClientBuilder clientbuilder = HttpClients.custom();

      //Setting the SSLConnectionSocketFactory
      clientbuilder = clientbuilder.setSSLSocketFactory(sslConSocFactory);

      //Building the CloseableHttpClient
      CloseableHttpClient httpclient = clientbuilder.build();

      //Creating the HttpGet request
      HttpGet httpget = new HttpGet("https://www.tw511.com/");

      //Executing the request
      HttpResponse httpresponse = httpclient.execute(httpget);

      //printing the status line
      System.out.println(httpresponse.getStatusLine());

      //Retrieving the HttpEntity and displaying the no.of bytes read
      HttpEntity entity = httpresponse.getEntity();
      if (entity != null) {
         System.out.println(EntityUtils.toByteArray(entity).length);
      } 
   }
}

執行上面範例程式碼,得到以下結果:

HTTP/1.1 200 OK
1270