日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

okhttp连接池_OkHttp配置HTTPS访问+服务器部署

發(fā)布時間:2024/9/19 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 okhttp连接池_OkHttp配置HTTPS访问+服务器部署 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1 概述

OkHttp配置HTTPS訪問,核心為以下三個部分: - sslSocketFactory() - HostnameVerifier - X509TrustManager

第一個是ssl套接字工廠,第二個用來驗證主機名,第三個是證書信任器管理類.通過OkHttp實現(xiàn)HTTPS訪問需要自己實現(xiàn)以上三部分.另外還簡單提及了服務器端的部署,用的是Tomcat9,最后是一些常見問題的可能解決方案.

2 OkHttp介紹

OkHttp是一款開源的處理網(wǎng)絡請求的輕量級框架,有Square公司貢獻,用于替代HttpUrlConnection與Apache HttpClient,目前Github上有36.4k的star.優(yōu)點有 - 共享socket,HTTP/2支持所有連接到同一個主機的請求共享socket - 連接池可以減少請求延遲 - 緩存響應數(shù)據(jù)減少重復的網(wǎng)絡請求 - 自動處理gzip壓縮

總的來說OkHttp是一款支持get/post請求,支持文件上傳/下載的優(yōu)秀的HTTP框架.

3 準備工作

  • 一臺服務器
  • 一個域名
  • 一個證書

什么?都沒有?買! 當然證書可以不用買,可以使用openssl之類的工具生成,不過自簽名的證書后面驗證的時候會有點麻煩,建議還是購買.

4 OkHttp部分

4.1 暴力方案

public static String test() {OkHttpClient client = new OkHttpClient.Builder().sslSocketFactory(createSSLSocketFactory(), new TrustAllCerts()).hostnameVerifier(new TrustAllHostnameVerifier()).build();String url = "https://xxxxxxx"; //修改成自己的urlRequest request = new Request.Builder().url(url).build();Call call = build.newCall(request);Response response = call.execute();if(response.body() != null){String result = response.body().string();//處理result} }private static class TrustAllCerts 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[0];} }private static class TrustAllHostnameVerifier implements HostnameVerifier {public boolean verify(String hostname, SSLSession session) { return true; } }private static SSLSocketFactory createSSLSocketFactory() {SSLSocketFactory ssfFactory = null;try {SSLContext sc = SSLContext.getInstance("TLS");sc.init(null, new TrustManager[]{new TrustAllCerts()}, new SecureRandom());ssfFactory = sc.getSocketFactory();} catch (Exception e) {e.printStackTrace();}return ssfFactory; }

這是一種暴力的方案,看類名就知道了,信任所有的證書與主機:

public boolean verify(String hostname, SSLSession session) { return true; }

這個方法直接返回true,也就是信任所有的主機.

public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {} public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}

這里兩個check函數(shù)沒有做任何的工作,表示接受任意的客戶端與服務端的證書.這樣寫的話相當于是使用了一個沒用的TrustManager,這樣還不如不加密,不推薦使用.

4.2 推薦方案

從兩方面入手修改,一是從X509TrustManager入手,二是從HostnameVerifier入手.

4.2.1 HostnameVerifier

先說個簡單的,這里主要是驗證主機名,簡單的話,可以如下實現(xiàn):

HostnameVerifier hnv = new HostnameVerifier() {@Overridepublic boolean verify(String hostname, SSLSession session) {if("www.test.com".equals(hostname)){ return true; } else { HostnameVerifier hv = HttpsURLConnection.getDefaultHostnameVerifier();return hv.verify(hostname, session);}} };

這里驗證主機名是http://www.test.com就返回true,實現(xiàn)得比較簡單,業(yè)務復雜的話可以結(jié)合配置中心,黑/白名單等動態(tài)校驗.

4.2.2 X509TrustManager

這里其實有兩種方式,一種是以流的方式添加信任證書:

private static X509TrustManager trustManagerForCertificates(InputStream in)throws GeneralSecurityException {CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");Collection<? extends Certificate> certificates = certificateFactory.generateCertificates(in);if (certificates.isEmpty()) {throw new IllegalArgumentException("expected non-empty set of trusted certificates");}char[] password = "password".toCharArray(); // 這里可以使用任意密碼KeyStore keyStore = newEmptyKeyStore(password);int index = 0;for (Certificate certificate : certificates) {String certificateAlias = Integer.toString(index++);keyStore.setCertificateEntry(certificateAlias, certificate);}// Use it to build an X509 trust manager.KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());keyManagerFactory.init(keyStore, password);TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());trustManagerFactory.init(keyStore);TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)){throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(trustManagers));}return (X509TrustManager) trustManagers[0]; }

完整代碼見文末.這里把工具類的方法實現(xiàn)成了靜態(tài),調(diào)用時可以直接:

OKHTTP.send("https://xxxxx");

另一種方式是直接自定義一個TrustManager,重寫里面的三個方法:

SSLContext context = SSLContext.getInstance("TLS"); context.init(null, new TrustManager[]{new X509TrustManager() {@Overridepublic void checkClientTrusted(X509Certificate[] chain,String authType) throws CertificateException {}@Overridepublic void checkServerTrusted(X509Certificate[] chain,String authType) throws CertificateException {for (X509Certificate cert : chain) {// Make sure that it hasn't expired.cert.checkValidity();// Verify the certificate's public key chain.try {cert.verify(((X509Certificate) ca).getPublicKey());} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (InvalidKeyException e) {e.printStackTrace();} catch (NoSuchProviderException e) {e.printStackTrace();} catch (SignatureException e) {e.printStackTrace();}}}@Overridepublic X509Certificate[] getAcceptedIssuers() {return new X509Certificate[0];}} }, null);

第一個方法為

@Override public void checkClientTrusted(X509Certificate[] chain,String authType) throws CertificateException {}

該方法檢查客戶端的證書,由于不需要對客戶端進行認證,默認即可. 第二個方法為

@Override public void checkServerTrusted(X509Certificate[] chain,String authType)

該方法檢查服務器的證書,若不信任該證書則拋出異常,通過自己實現(xiàn)該方法可以信任任何自己指定的證書,不做任何處理的話,不會拋出任何異常,相當于信任所有證書.這里檢查了證書是否過期以及證書的簽名是否匹配. 第三個方法為

@Override public X509Certificate[] getAcceptedIssuers() {return new X509Certificate[0]; }

返回受信任的X509證書數(shù)組.

這種方法筆者沒有試過,僅供參考.

5 服務器部署

服務器用的是Tomcat,簡單介紹一下部署.

5.1 上傳工程

后端處理用的Spring Boot的工程,就不演示了,使用IDEA打成war包后上傳到webapps下即可.

5.2 Tomcat配置

重點說一下Tomcat的配置,首先需要一個域名,修改conf/server.xml文件,找到默認的名叫l(wèi)ocalhost的Host:

然后直接復制Host標簽,把name修改成自己的域名即可.

然后是證書的配置,筆者的證書在某某云上購買的,這里提供了幾種格式的證書下載:

Tomcat的是兩個文件,一個是pfx文件,一個是密碼文件,把pfx文件上傳到服務器的Tomcat后,繼續(xù)修改server.xml,大約87行左右的位置(Tomcat版本9.0.33):

修改如下:

添加了scheme,secure,keystoreFile,keystoreType,keystorePass,clientAuth,sslProtocol配置,同時去掉里面的<SSLHostConfig>,keystoreFile是剛才的pfx文件,采用絕對路徑,keystorePass是密碼. 另外默認的端口為8443,這里修改成了8123. 重啟Tomcat后輸入

https://www.test.com:port

進行測試

這樣就成功了.

6 驗證與源碼

這個因為沒有完整的Demo很難做驗證,具體來說前端用的OkHttp核心都介紹了,后端的話服務器Tomcat也介紹了,用Spring Boot做個Demo應該不難.

這里只給出了工具類OKHTTP的源碼:

2293736867/OkHttp-HTTPS-demo?github.com

7 常見問題

7.1 Tomcat HTTPS無法訪問

  • 證書文件錯誤,不過這個可能性比較少.
  • 配置錯誤,請檢查配置文件是否正確,可以ps -ef | grep tomcat查看Tomcat是否開啟以及查看logs/catalina.out日志.
  • 端口錯誤,訪問的端口需要與<Connector>中的端口對應(Tomcat默認的HTTPS端口為8443,筆者居然看成了8433,然后netstat 無數(shù)次都沒有看到被監(jiān)聽...)
  • 安全組/防火墻問題,云服務器的話需要在安全組配置中開啟相應端口,同時應查看有沒有把某個ip列入黑名單導致無法訪問.防火墻的話這里主要指iptables,如果沒有開啟的話不需要理會,如果開啟的話需要開放對應端口.

7.2 OkHttp HTTPS無法訪問

  • 無法讀取證書文件:需要把證書文件放在工程對應路徑下讀取,比如AS中放在assets下然后使用getAssets().open("http://xxx.xxx")獲取,Maven工程的話放在resources下直接使用FileInputStream獲取.
  • singed fields invalid:

證書文件格式錯誤,使用.crt/.pem等證書.

  • Signature does not match:這個有可能是使用openssl自生成證書在驗證的時候出現(xiàn)的異常,可能的解決辦法是轉(zhuǎn)換證書的格式,如果不行就重新生成一次證書.

8 參考鏈接

Android App 安全的HTTPS 通信?pingguohe.netAndroid OkHttp實現(xiàn)HTTPS訪問,支持Android 4.X系統(tǒng)HTTPS訪問?blog.csdn.netAndroid使用OkHttp請求自簽名的https網(wǎng)站?www.jianshu.com

總結(jié)

以上是生活随笔為你收集整理的okhttp连接池_OkHttp配置HTTPS访问+服务器部署的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。