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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > Android >内容正文

Android

Android Https相关完全解析 当OkHttp遇到Https

發(fā)布時(shí)間:2025/4/16 Android 55 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android Https相关完全解析 当OkHttp遇到Https 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

http://blog.csdn.net/lmj623565791/article/details/48129405; 本文出自:【張鴻洋的博客】

1. 概述

其實(shí)這篇文章理論上不限于okhttp去訪問自簽名的網(wǎng)站,不過(guò)接上篇博文了,就叫這個(gè)了。首先要了解的事,okhttp默認(rèn)情況下是支持https協(xié)議的網(wǎng)站的,比如https://www.baidu.com,https://github.com/hongyangAndroid/okhttp-utils等,你可以直接通過(guò)okhttp請(qǐng)求試試。不過(guò)要注意的是,支持的https的網(wǎng)站基本都是CA機(jī)構(gòu)頒發(fā)的證書,默認(rèn)情況下是可以信任的。

當(dāng)然我們今天要說(shuō)的是自簽名的網(wǎng)站,什么叫自簽名呢?就是自己通過(guò)keytool去生成一個(gè)證書,然后使用,并不是CA機(jī)構(gòu)去頒發(fā)的。使用自簽名證書的網(wǎng)站,大家在使用瀏覽器訪問的時(shí)候,一般都是報(bào)風(fēng)險(xiǎn)警告,好在有個(gè)大名鼎鼎的網(wǎng)站就是這么干的,https://kyfw.12306.cn/otn/,點(diǎn)擊進(jìn)入12306的購(gòu)票頁(yè)面就能看到了。

如下界面:

大家可以嘗試拿okhttp訪問下:

OkHttpClientManager.getAsyn("https://kyfw.12306.cn/otn/", callack);1212

會(huì)爆出如下錯(cuò)誤

javax.net.ssl.SSLHandshakeException:java.security.cert.CertPathValidatorException:Trust anchor for certification path not found.123123

好了,本篇博文當(dāng)然不是去說(shuō)如何去訪問12306,而是以12306為例子來(lái)說(shuō)明如何去訪問自簽名證書的網(wǎng)站。因?yàn)椴糠珠_發(fā)者app與自己服務(wù)端交互的時(shí)候可能也會(huì)遇到自簽名證書的。甚至在開發(fā)安全級(jí)別很高的app時(shí),需要用到雙向證書的驗(yàn)證。

那么本篇博文的基本內(nèi)容包含:

  • https一些相關(guān)的知識(shí)
  • okhttp訪問自簽名https網(wǎng)站
  • 如何構(gòu)建一個(gè)支持https的服務(wù)器(這里主要為了測(cè)試多個(gè)證書的時(shí)候,如何去加載)
  • 如何進(jìn)行雙向證書驗(yàn)證

2. Https相關(guān)知識(shí)

關(guān)于特別理論的東西大家可以百度下自己去了解下,這里就簡(jiǎn)單說(shuō)一下,HTTPS相當(dāng)于HTTP的安全版本了,為什么安全呢?

因?yàn)樗贖TTP的之下加入了SSL (Secure Socket Layer),安全的基礎(chǔ)就靠這個(gè)SSL了。SSL位于TCP/IP和HTTP協(xié)議之間,那么它到底能干嘛呢?

它能夠:

  • 認(rèn)證用戶和服務(wù)器,確保數(shù)據(jù)發(fā)送到正確的客戶機(jī)和服務(wù)器;(驗(yàn)證證書)
  • 加密數(shù)據(jù)以防止數(shù)據(jù)中途被竊取;(加密)
  • 維護(hù)數(shù)據(jù)的完整性,確保數(shù)據(jù)在傳輸過(guò)程中不被改變。(摘要算法)

以上3條來(lái)自百度

下面我們簡(jiǎn)單描述下HTTPS的工作原理,大家就能對(duì)應(yīng)的看到上面3條作用的身影了:

HTTPS在傳輸數(shù)據(jù)之前需要客戶端(瀏覽器)與服務(wù)端(網(wǎng)站)之間進(jìn)行一次握手,在握手過(guò)程中將確立雙方加密傳輸數(shù)據(jù)的密碼信息。握手過(guò)程的簡(jiǎn)單描述如下:

  • 瀏覽器將自己支持的一套加密算法、HASH算法發(fā)送給網(wǎng)站。
  • 網(wǎng)站從中選出一組加密算法與HASH算法,并將自己的身份信息以證書的形式發(fā)回給瀏覽器。證書里面包含了網(wǎng)站地址,加密公鑰,以及證書的頒發(fā)機(jī)構(gòu)等信息。
  • 瀏覽器獲得網(wǎng)站證書之后,開始驗(yàn)證證書的合法性,如果證書信任,則生成一串隨機(jī)數(shù)字作為通訊過(guò)程中對(duì)稱加密的秘鑰。然后取出證書中的公鑰,將這串?dāng)?shù)字以及HASH的結(jié)果進(jìn)行加密,然后發(fā)給網(wǎng)站。
  • 網(wǎng)站接收瀏覽器發(fā)來(lái)的數(shù)據(jù)之后,通過(guò)私鑰進(jìn)行解密,然后HASH校驗(yàn),如果一致,則使用瀏覽器發(fā)來(lái)的數(shù)字串使加密一段握手消息發(fā)給瀏覽器。
  • 瀏覽器解密,并HASH校驗(yàn),沒有問題,則握手結(jié)束。接下來(lái)的傳輸過(guò)程將由之前瀏覽器生成的隨機(jī)密碼并利用對(duì)稱加密算法進(jìn)行加密。
  • 握手過(guò)程中如果有任何錯(cuò)誤,都會(huì)使加密連接斷開,從而阻止了隱私信息的傳輸。

    ok,以上的流程不一定完全正確,基本就是這樣,當(dāng)然如果有明顯錯(cuò)誤歡迎指出。

    根據(jù)上面的流程,我們可以看到服務(wù)器端會(huì)有一個(gè)證書,在交互過(guò)程中客戶端需要去驗(yàn)證證書的合法性,對(duì)于權(quán)威機(jī)構(gòu)頒發(fā)的證書當(dāng)然我們會(huì)直接認(rèn)為合法。對(duì)于自己造的證書,那么我們就需要去校驗(yàn)合法性了,也就是說(shuō)我們只需要讓OkhttpClient去信任這個(gè)證書就可以暢通的進(jìn)行通信了。

    當(dāng)然,對(duì)于自簽名的網(wǎng)站的訪問,網(wǎng)上的部分的做法是直接設(shè)置信任所有的證書,對(duì)于這種做法肯定是有風(fēng)險(xiǎn)的,所以這里我們不去介紹了,有需要自己去查。

    下面我們?nèi)タ紤],如何讓OkHttpClient去信任我們的證書,接下里的例子就是靠12306這個(gè)福利站點(diǎn)了。

    首先導(dǎo)出12306的證書,這里12306提供了下載地址:12306證書點(diǎn)擊下載

    下載完成,解壓拿到里面的srca.cer,一會(huì)需要使用。ps:即使沒有提供下載,也可以通過(guò)瀏覽器導(dǎo)出的,自行百度。

    3. 代碼

    3.1 訪問自簽名的網(wǎng)站

    首先把我們下載的srca.cer放到assets文件夾下,其實(shí)你可以隨便放哪,反正能讀取到就行。

    然后在我們的OkHttpClientManager里面添加如下的方法:

    public void setCertificates(InputStream... certificates) {try{CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());keyStore.load(null);int index = 0;for (InputStream certificate : certificates){String certificateAlias = Integer.toString(index++);keyStore.setCertificateEntry(certificateAlias, certificateFactory.generateCertificate(certificate));try{if (certificate != null)certificate.close();} catch (IOException e){}}SSLContext sslContext = SSLContext.getInstance("TLS");TrustManagerFactory trustManagerFactory =TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());trustManagerFactory.init(keyStore);sslContext.init( null,trustManagerFactory.getTrustManagers(),new SecureRandom());mOkHttpClient.setSslSocketFactory(sslContext.getSocketFactory());} catch (Exception e){e.printStackTrace();}}

    為了代碼可讀性,我把異常捕獲的部分簡(jiǎn)化了,可以看到我們提供了一個(gè)方法傳入InputStream流,InputStream就對(duì)應(yīng)于我們證書的輸入流。

    代碼內(nèi)部,我們:

    • 構(gòu)造CertificateFactory對(duì)象,通過(guò)它的generateCertificate(is)方法得到Certificate。
    • 然后講得到的Certificate放入到keyStore中。
    • 接下來(lái)利用keyStore去初始化我們的TrustManagerFactory
    • 由trustManagerFactory.getTrustManagers獲得TrustManager[]初始化我們的SSLContext
    • 最后,設(shè)置我們mOkHttpClient.setSslSocketFactory即可。

    這樣就完成了我們代碼的編寫,其實(shí)挺短的,當(dāng)客戶端進(jìn)行SSL連接時(shí),就可以根據(jù)我們?cè)O(shè)置的證書去決定是否新人服務(wù)端的證書。

    記得在Application中進(jìn)行初始化:

    public class MyApplication extends Application {@Overridepublic void onCreate(){super.onCreate();try{OkHttpClientManager.getInstance().setCertificates(getAssets().open("srca.cer"));} catch (IOException e){e.printStackTrace();}}

    然后嘗試以下代碼訪問12306的網(wǎng)站:

    OkHttpClientManager.getAsyn("https://kyfw.12306.cn/otn/", new OkHttpClientManager.ResultCallback<String>() {@Overridepublic void onError(Request request, Exception e){e.printStackTrace();}@Overridepublic void onResponse(String u){mTv.setText(u);} });

    這樣即可訪問成功。完整代碼已經(jīng)更新至:https://github.com/hongyangAndroid/okhttp-utils,可以下載里面的sample進(jìn)行測(cè)試,里面包含12306的證書。

    ok,到這就可以看到使用Okhttp可以很方便的應(yīng)對(duì)自簽名的網(wǎng)站的訪問,只需要拿到包含公鑰的證書即可。

    3.2 使用字符串替代證書

    下面繼續(xù),有些人可能覺得把證書copy到assets下還是覺得不舒服,其實(shí)我們還可以將證書中的內(nèi)容提取出來(lái),寫成字符串常量,這樣就不需要證書根據(jù)著app去打包了。

    zhydeMacBook-Pro:temp zhy$ keytool -printcert -rfc -file srca.cer -----BEGIN CERTIFICATE----- MIICmjCCAgOgAwIBAgIIbyZr5/jKH6QwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCQ04xKTAn BgNVBAoTIFNpbm9yYWlsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRTUkNBMB4X DTA5MDUyNTA2NTYwMFoXDTI5MDUyMDA2NTYwMFowRzELMAkGA1UEBhMCQ04xKTAnBgNVBAoTIFNp bm9yYWlsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRTUkNBMIGfMA0GCSqGSIb3 DQEBAQUAA4GNADCBiQKBgQDMpbNeb34p0GvLkZ6t72/OOba4mX2K/eZRWFfnuk8e5jKDH+9BgCb2 9bSotqPqTbxXWPxIOz8EjyUO3bfR5pQ8ovNTOlks2rS5BdMhoi4sUjCKi5ELiqtyww/XgY5iFqv6 D4Pw9QvOUcdRVSbPWo1DwMmH75It6pk/rARIFHEjWwIDAQABo4GOMIGLMB8GA1UdIwQYMBaAFHle tne34lKDQ+3HUYhMY4UsAENYMAwGA1UdEwQFMAMBAf8wLgYDVR0fBCcwJTAjoCGgH4YdaHR0cDov LzE5Mi4xNjguOS4xNDkvY3JsMS5jcmwwCwYDVR0PBAQDAgH+MB0GA1UdDgQWBBR5XrZ3t+JSg0Pt x1GITGOFLABDWDANBgkqhkiG9w0BAQUFAAOBgQDGrAm2U/of1LbOnG2bnnQtgcVaBXiVJF8LKPaV 23XQ96HU8xfgSZMJS6U00WHAI7zp0q208RSUft9wDq9ee///VOhzR6Tebg9QfyPSohkBrhXQenvQ og555S+C3eJAAVeNCTeMS3N/M5hzBRJAoffn3qoYdAO1Q8bTguOi+2849A== -----END CERTIFICATE-----123456789101112131415123456789101112131415

    使用keytool命令,以rfc樣式輸出。keytool命令是JDK里面自帶的。

    有了這個(gè)字符串以后,我們就不需要srca.cer這個(gè)文件了,直接編寫以下代碼:

    public class MyApplication extends Application {private String CER_12306 = "-----BEGIN CERTIFICATE-----\n" +"MIICmjCCAgOgAwIBAgIIbyZr5/jKH6QwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCQ04xKTAn\n" +"BgNVBAoTIFNpbm9yYWlsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRTUkNBMB4X\n" +"DTA5MDUyNTA2NTYwMFoXDTI5MDUyMDA2NTYwMFowRzELMAkGA1UEBhMCQ04xKTAnBgNVBAoTIFNp\n" +"bm9yYWlsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRTUkNBMIGfMA0GCSqGSIb3\n" +"DQEBAQUAA4GNADCBiQKBgQDMpbNeb34p0GvLkZ6t72/OOba4mX2K/eZRWFfnuk8e5jKDH+9BgCb2\n" +"9bSotqPqTbxXWPxIOz8EjyUO3bfR5pQ8ovNTOlks2rS5BdMhoi4sUjCKi5ELiqtyww/XgY5iFqv6\n" +"D4Pw9QvOUcdRVSbPWo1DwMmH75It6pk/rARIFHEjWwIDAQABo4GOMIGLMB8GA1UdIwQYMBaAFHle\n" +"tne34lKDQ+3HUYhMY4UsAENYMAwGA1UdEwQFMAMBAf8wLgYDVR0fBCcwJTAjoCGgH4YdaHR0cDov\n" +"LzE5Mi4xNjguOS4xNDkvY3JsMS5jcmwwCwYDVR0PBAQDAgH+MB0GA1UdDgQWBBR5XrZ3t+JSg0Pt\n" +"x1GITGOFLABDWDANBgkqhkiG9w0BAQUFAAOBgQDGrAm2U/of1LbOnG2bnnQtgcVaBXiVJF8LKPaV\n" +"23XQ96HU8xfgSZMJS6U00WHAI7zp0q208RSUft9wDq9ee///VOhzR6Tebg9QfyPSohkBrhXQenvQ\n" +"og555S+C3eJAAVeNCTeMS3N/M5hzBRJAoffn3qoYdAO1Q8bTguOi+2849A==\n" +"-----END CERTIFICATE-----";@Overridepublic void onCreate(){super.onCreate();OkHttpClientManager.getInstance().setCertificates(new Buffer().writeUtf8(CER_12306).inputStream()); }

    注意Buffer是okio包下的,okhttp依賴okio。

    ok,這樣就省去將cer文件一起打包進(jìn)入apk了。

    接下來(lái)介紹,如何去生成證書以及在tomcat服務(wù)器下使用自簽名證書部署服務(wù)。如果大家沒這方面需要可以簡(jiǎn)單了解下。

    4. tomcat下使用自簽名證書部署服務(wù)

    首先自行下載個(gè)tomcat的壓縮包。

    既然我們要支持https,那么肯定需要個(gè)證書,如何生成證書呢?使用keytool非常簡(jiǎn)單。

    4.1 生成證書

    zhydeMacBook-Pro:temp zhy$ keytool -genkey -alias zhy_server -keyalg RSA -keystore zhy_server.jks -validity 3600 -storepass 123456 您的名字與姓氏是什么?[Unknown]: zhang 您的組織單位名稱是什么?[Unknown]: zhang 您的組織名稱是什么?[Unknown]: zhang 您所在的城市或區(qū)域名稱是什么?[Unknown]: xian 您所在的省/市/自治區(qū)名稱是什么?[Unknown]: shanxi 該單位的雙字母國(guó)家/地區(qū)代碼是什么?[Unknown]: cn CN=zhang, OU=zhang, O=zhang, L=xian, ST=shanxi, C=cn是否正確?[]: y輸入 <zhy_server> 的密鑰口令(如果和密鑰庫(kù)口令相同, 按回車):

    使用以上命令即可生成一個(gè)證書請(qǐng)求文件zhy_server.jks,注意密鑰庫(kù)口令為:123456.

    接下來(lái)利用zhy_server.jks來(lái)簽發(fā)證書:

    zhydeMacBook-Pro:temp zhy$ keytool -export -alias zhy_server-file zhy_server.cer-keystore zhy_server.jks-storepass 123456 12341234

    即可生成包含公鑰的證書zhy_server.cer。

    4.2 配置Tomcat

    找到tomcat/conf/sever.xml文件,并以文本形式打開。

    在Service標(biāo)簽中,加入:

    <Connector SSLEnabled="true" acceptCount="100" clientAuth="false"disableUploadTimeout="true" enableLookups="true" keystoreFile="" keystorePass="123456" maxSpareThreads="75"maxThreads="200" minSpareThreads="5" port="8443"protocol="org.apache.coyote.http11.Http11NioProtocol" scheme="https"secure="true" sslProtocol="TLS"/>

    注意keystoreFile的值為我們剛才生成的jks文件的路徑:/Users/zhy/ temp/zhy_server.jks(填寫你的路徑).keystorePass值為密鑰庫(kù)密碼:123456。

    然后啟動(dòng)即可,對(duì)于命令行啟動(dòng),依賴環(huán)境變量JAVA_HOME;如果在MyEclispe等IDE下啟動(dòng)就比較隨意了。

    啟動(dòng)成功以后,打開瀏覽器輸入url:https://localhost:8443/即可看到證書不可信任的警告了。選擇打死也要進(jìn)入,即可進(jìn)入tomcat默認(rèn)的主頁(yè):

    如果你在此tomcat中部署了項(xiàng)目,即可按照如下url方式訪問:
    https://192.168.1.103:8443/項(xiàng)目名/path,沒有部署也沒關(guān)系,直接拿默認(rèn)的主頁(yè)進(jìn)行測(cè)試了,拿它的html字符串。

    對(duì)于訪問,還需要說(shuō)么,我們剛才已經(jīng)生成了zhy_server.cer證書。你可以選擇copy到assets,或者通過(guò)命令拿到內(nèi)部包含的字符串。我們這里選擇copy。

    依然選擇在Application中設(shè)置信任證書:

    public class MyApplication extends Application {private String CER_12306 = "省略...";@Overridepublic void onCreate(){super.onCreate();try{OkHttpClientManager.getInstance().setCertificates(new Buffer().writeUtf8(CER_12306).inputStream(),getAssets().open("zhy_server.cer"));} catch (IOException e){e.printStackTrace();}} }

    ok,這樣就能正常訪問你部署的https項(xiàng)目中的服務(wù)了,沒有部署項(xiàng)目的嘗試拿https://服務(wù)端ip:8443/測(cè)試即可。

    注意:不要使用localhost,真機(jī)測(cè)試保證手機(jī)和服務(wù)器在同一局域網(wǎng)段內(nèi)。

    ok,到此我們介紹完了如果搭建https服務(wù)和如何訪問,基本上可以應(yīng)付極大部分的需求了。當(dāng)然還是極少數(shù)的應(yīng)用需要雙向證書驗(yàn)證,比如銀行、金融類app,我們一起來(lái)了解下。

    5. 雙向證書驗(yàn)證

    首先對(duì)于雙向證書驗(yàn)證,也就是說(shuō),客戶端也會(huì)有個(gè)“kjs文件”,服務(wù)器那邊會(huì)同時(shí)有個(gè)“cer文件”與之對(duì)應(yīng)。

    我們已經(jīng)生成了zhy_server.kjs和zhy_server.cer文件。

    接下來(lái)按照生成證書的方式,再生成一對(duì)這樣的文件,我們命名為:zhy_client.kjs,zhy_client.cer.

    6. 配置服務(wù)端

    首先我們配置服務(wù)端:

    服務(wù)端的配置比較簡(jiǎn)單,依然是剛才的Connector標(biāo)簽,不過(guò)需要添加些屬性。

    <Connector 其他屬性與前面一致 clientAuth="true"truststoreFile="/Users/zhy/temp/zhy_client.cer"/> 12341234

    將clientAuth設(shè)置為true,并且多添加一個(gè)屬性truststoreFile,理論上值為我們的cer文件。這么加入以后,嘗試啟動(dòng)服務(wù)器,會(huì)發(fā)生錯(cuò)誤:Invalid keystore format。說(shuō)keystore的格式不合法。

    我們需要對(duì)zhy_client.cer執(zhí)行以下步驟,將證書添加到kjs文件中。

    keytool -import -alias zhy_client-file zhy_client.cer -keystore zhy_client_for_sever.jks1212

    接下里修改server.xml為:

    <Connector 其他屬性與前面一致clientAuth="true"truststoreFile="/Users/zhy/temp/zhy_client_for_sever.jks"/> 12341234

    此時(shí)啟動(dòng)即可。

    此時(shí)再拿瀏覽器已經(jīng)無(wú)法訪問到我們的服務(wù)了,會(huì)顯示基于證書的身份驗(yàn)證失敗。

    我們將目標(biāo)來(lái)到客戶端,即我們的Android端,我們的Android端,如何設(shè)置kjs文件呢。

    7. 配置app端

    目前我們app端依靠的應(yīng)該是zhy_client.kjs。

    ok,大家還記得,我們?cè)谥С謍ttps的時(shí)候調(diào)用了這么倆行代碼:

    sslContext.init(null, trustManagerFactory.getTrustManagers(),new SecureRandom()); mOkHttpClient.setSslSocketFactory(sslContext.getSocketFactory());123123

    注意sslContext.init的第一個(gè)參數(shù)我們傳入的是null,第一個(gè)參數(shù)的類型實(shí)際上是KeyManager[] km,主要就用于管理我們客戶端的key。

    于是代碼可以這么寫:

    public void setCertificates(InputStream... certificates) {try{CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());keyStore.load(null);int index = 0;for (InputStream certificate : certificates){String certificateAlias = Integer.toString(index++);keyStore.setCertificateEntry(certificateAlias, certificateFactory.generateCertificate(certificate));try{if (certificate != null)certificate.close();} catch (IOException e){}}SSLContext sslContext = SSLContext.getInstance("TLS");TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());trustManagerFactory.init(keyStore);//初始化keystoreKeyStore clientKeyStore = KeyStore.getInstance(KeyStore.getDefaultType());clientKeyStore.load(mContext.getAssets().open("zhy_client.jks"), "123456".toCharArray());KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());keyManagerFactory.init(clientKeyStore, "123456".toCharArray());sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom());mOkHttpClient.setSslSocketFactory(sslContext.getSocketFactory());} catch (Exception e){e.printStackTrace();}}

    核心代碼其實(shí)就是:

    //初始化keystore KeyStore clientKeyStore = KeyStore.getInstance(KeyStore.getDefaultType()); clientKeyStore.load(mContext.getAssets().open("zhy_client.jks"), "123456".toCharArray());KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); keyManagerFactory.init(clientKeyStore, "123456".toCharArray());sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom()); 123456789123456789

    然而此時(shí)啟動(dòng)會(huì)報(bào)錯(cuò):Java.io.IOException: Wrong version of key store.

    為什么呢?

    因?yàn)?#xff1a;Java平臺(tái)默認(rèn)識(shí)別jks格式的證書文件,但是android平臺(tái)只識(shí)別bks格式的證書文件。

    這么就糾結(jié)了,我們需要將我們的jks文件轉(zhuǎn)化為bks文件,怎么轉(zhuǎn)化呢?

    這里的方式可能比較多,大家可以百度,我推薦一種方式:

    – 去Portecle下載Download portecle-1.9.zip (3.4 MB)。

    解壓后,里面包含bcprov.jar文件,使用jave -jar bcprov.jar即可打開GUI界面。

    按照上圖即可將zhy_client.jks轉(zhuǎn)化為zhy_client.bks。

    然后將zhy_client.bks拷貝到assets目錄下,修改代碼為:

    //初始化keystore KeyStore clientKeyStore = KeyStore.getInstance("BKS"); clientKeyStore.load(mContext.getAssets().open("zhy_client.bks"), "123456".toCharArray());KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); keyManagerFactory.init(clientKeyStore, "123456".toCharArray());sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom());1234567812345678

    再次運(yùn)行即可。然后就成功的做到了雙向的驗(yàn)證,關(guān)于雙向這塊大家了解下即可。

    源碼都在https://github.com/hongyangAndroid/okhttp-utils之中。

    ok,到此本篇博文就結(jié)束了,文章相當(dāng)?shù)拈L(zhǎng)~~ 關(guān)于okhttp在https協(xié)議下的使用,應(yīng)該沒什么問題。

    ps:如果大家對(duì)okhttp-utils有任何建議,非常歡迎提出,最近根據(jù)大家的需求修改相當(dāng)頻繁

    總結(jié)

    以上是生活随笔為你收集整理的Android Https相关完全解析 当OkHttp遇到Https的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

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