Apache HttpClient - 自定義SSL上下文
使用安全套接字層 (SSL),您可以建立客戶端和伺服器之間的安全連線。它有助於保護敏感資訊,例如信用卡號碼、使用者名稱、密碼、PIN 碼等。
您可以使用HttpClient庫建立自己的SSL上下文,使連線更安全。
按照以下步驟使用HttpClient庫自定義SSLContext:
步驟1 - 建立SSLContextBuilder物件
SSLContextBuilder是SSLContext物件的構建器。使用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://example.com/");
步驟9 - 執行請求
使用execute()方法執行請求。
//Executing the request HttpResponse httpresponse = httpclient.execute(httpget);
示例
以下示例演示了SSLContext的自定義:
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://example.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