HTTPS 其實就是 HTTP + SSL/TLS 的合體,它其實還是 HTTP 協議,只是在外面加了一層,SSL 是一種加密安全協議
引入 SSL 的目的是為了解決 HTTP 協議在不可信網絡中使用明文傳輸數據導致的安全性問題
SSL/TLS協議及其握手過程
在 SSL/TLS 握手的過程中,客戶端和服務器彼此交換並驗證證書,並協商出一個 “對話密鑰” ,后續的所有通信都使用這個 “對話密鑰” 進行加密,保證通信安全
1 打招呼
當用戶通過瀏覽器訪問 HTTPS 站點時,瀏覽器會向服務器打個招呼,服務器也會和瀏覽器打個招呼。所謂的打招呼,實際上是告訴彼此各自的 SSL/TLS 版本號以及各自支持的加密算法等,讓彼此有一個初步了解
2 表明身份、驗證身份
第二步是整個過程中最復雜的一步,也是 HTTPS 通信中的關鍵。為了保證通信的安全,首先要保證我正在通信的人確實就是那個我想與之通信的人,服務器會發送一個證書來表明自己的身份,瀏覽器根據證書里的信息進行核實。如果是雙向認證的話,瀏覽器也會向服務器發送客戶端證書
雙方的身份都驗證沒問題之后,瀏覽器會和服務器協商出一個 “對話密鑰”
3 通信
至此,握手就結束了。雙方開始聊天,並通過 “對話密鑰” 加密通信的數據。
1 工具類
package dd.com; import java.io.IOException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.HttpClient; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.scheme.SchemeRegistry; import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; public class HttpUtils { private static RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(15000).setConnectTimeout(15000) .setConnectionRequestTimeout(15000).build(); public static String sendHttpGet(String url) { HttpGet httpGet = new HttpGet(url); CloseableHttpClient httpClient = null; CloseableHttpResponse response = null; HttpEntity entity = null; String responseContent = null; try { // 創建默認的httpClient實例. httpClient = HttpClients.createDefault(); httpGet.setConfig(requestConfig); // 執行請求 response = httpClient.execute(httpGet); entity = response.getEntity(); responseContent = EntityUtils.toString(entity, "UTF-8"); } catch (Exception e) { e.printStackTrace(); } finally { try { // 關閉連接,釋放資源 if (response != null) { response.close(); } if (httpClient != null) { httpClient.close(); } } catch (IOException e) { e.printStackTrace(); } } return responseContent; } /** * 發送 post請求 * * @param httpUrl 地址 * @param maps 參數 */ public static String sendHttpPost(String httpUrl, Map<String, String> maps) { HttpPost httpPost = new HttpPost(httpUrl);// 創建httpPost // 創建參數隊列 List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(); for (String key : maps.keySet()) { nameValuePairs.add(new BasicNameValuePair(key, maps.get(key))); } try { httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8")); } catch (Exception e) { e.printStackTrace(); } CloseableHttpClient httpClient = null; CloseableHttpResponse response = null; HttpEntity entity = null; String responseContent = null; try { // 創建默認的httpClient實例. httpClient = HttpClients.createDefault(); httpPost.setConfig(requestConfig); // 執行請求 response = httpClient.execute(httpPost); entity = response.getEntity(); responseContent = EntityUtils.toString(entity, "UTF-8"); } catch (Exception e) { e.printStackTrace(); } finally { try { // 關閉連接,釋放資源 if (response != null) { response.close(); } if (httpClient != null) { httpClient.close(); } } catch (IOException e) { e.printStackTrace(); } } return responseContent; } @SuppressWarnings("unchecked") public static String sendHttpsPost(String url, Map<String, String> map, String charset) { if (null == charset) { charset = "utf-8"; } HttpClient httpClient = null; HttpPost httpPost = null; String result = null; try { httpClient = new SSLClient(); httpPost = new HttpPost(url); // 設置參數 List<NameValuePair> list = new ArrayList<NameValuePair>(); Iterator iterator = map.entrySet().iterator(); while (iterator.hasNext()) { Entry<String, String> elem = (Entry<String, String>) iterator.next(); list.add(new BasicNameValuePair(elem.getKey(), elem.getValue())); } if (list.size() > 0) { UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list, charset); httpPost.setEntity(entity); } HttpResponse response = httpClient.execute(httpPost); if (response != null) { HttpEntity resEntity = response.getEntity(); if (resEntity != null) { result = EntityUtils.toString(resEntity, charset); } } } catch (Exception ex) { ex.printStackTrace(); } return result; } public static String sendHttpsGet(String url, String charset) { if (null == charset) { charset = "utf-8"; } HttpClient httpClient = null; HttpGet httpGet = null; String result = null; try { httpClient = new SSLClient(); httpGet = new HttpGet(url); HttpResponse response = httpClient.execute(httpGet); if (response != null) { HttpEntity resEntity = response.getEntity(); if (resEntity != null) { result = EntityUtils.toString(resEntity, charset); } } } catch (Exception e) { e.printStackTrace(); } return result; } public static class SSLClient extends DefaultHttpClient { public SSLClient() throws Exception { super(); SSLContext ctx = SSLContext.getInstance("TLS"); X509TrustManager tm = new X509TrustManager() { @Override public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public X509Certificate[] getAcceptedIssuers() { return null; } }; ctx.init(null, new TrustManager[] { tm }, null); SSLSocketFactory ssf = new SSLSocketFactory(ctx, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); ClientConnectionManager ccm = this.getConnectionManager(); SchemeRegistry sr = ccm.getSchemeRegistry(); sr.register(new Scheme("https", 443, ssf)); } } }
2 maven 依賴 和 jdk 編譯版本
3 依賴的jar包