Android Https技術探索

最近在Https方面做了一些探索炊琉,在Android上做了一些實際應用,在此分享出來以便后查。

Https協(xié)議是什么

目前佃却,Https已經(jīng)成為了主流趨勢,無論在大型互聯(lián)網(wǎng)公司如BAT窘俺,還是小型創(chuàng)業(yè)公司饲帅,都逐漸將自己的服務切換成了Https复凳。Https能提供一種安全可靠的加密通信連接方式,有效防止信息泄密以及劫持等情況發(fā)生灶泵。因此育八,使用Https無論從用戶體驗還是企業(yè)長期利益來看,都是十分有益的赦邻。

Http協(xié)議

我們首先說說什么是Http協(xié)議髓棋?Http是一個屬于應用層的面向對象的協(xié)議,由于其簡捷惶洲、快速的方式按声,適用于分布式超媒體信息系統(tǒng)。

Http(超文本傳輸協(xié)議)是一個基于請求與響應模式的恬吕、無狀態(tài)的签则、應用層的協(xié)議,愁砹希基于TCP的連接方式渐裂,HTTP1.1版本中給出一種持續(xù)連接的機制,絕大多數(shù)的Web開發(fā)钠惩,都是構建在HTTP協(xié)議之上的Web應用柒凉。

順便說一句,Http1.1協(xié)議已經(jīng)是目前最主流的協(xié)議篓跛,但是新的Http2.0協(xié)議也已經(jīng)提出扛拨,在未來10年的時間內(nèi),必將逐漸登上主舞臺举塔。這種在應用層的推廣會比IPV6這種網(wǎng)絡層的推廣快很多。

Http URL(URL是一種特殊類型的URI求泰,包含了用于查找某個資源的足夠的信息)的格式如下:

http://host[":"port][abs_path]

Http的請求由三部分組成央渣,分別是:請求行、消息報頭渴频、請求正文芽丹。具體內(nèi)容可以查看WikiPedia,再次不多贅述卜朗。

SSL/TLS協(xié)議

那么什么是Https協(xié)議呢拔第?簡單來說,Https = Http + SSL/TLS场钉,即基于SSL的Http協(xié)議蚊俺,使用不同于Http協(xié)議的默認端口及一個加密、身份驗證層(Http與TCP之間)逛万。

Https實際上應用了Netscape的安全全套接字層(SSL泳猬,TLS則是SSL的升級版,修復了SSL的漏洞)作為Http應用層的子層。Https使用端口443得封,而不是像Http那樣使用端口80和TCP/IP進行通信埋心。SSL使用40位關鍵字作為RC4流加密算法,這對于商業(yè)信息的加密是合適的忙上。Https和SSL支持使用X.509數(shù)字認證拷呆,如果需要的話用戶可以確認發(fā)送者是誰。Https協(xié)議使用SSL在發(fā)送方把原始數(shù)據(jù)進行加密疫粥,然后在接受方進行解密茬斧,加密和解密需要發(fā)送方和接受方通過交換共知的密鑰來實現(xiàn),因此手形,所傳送的數(shù)據(jù)不容易被網(wǎng)絡黑客截獲和解密啥供。

客戶端在使用Https方式與Web服務器通信時有以下幾個步驟:

  1. 客戶使用Https的URL訪問Web服務器,要求與Web服務器建立SSL連接库糠。
  2. Web服務器收到客戶端請求后伙狐,會將網(wǎng)站的證書信息(證書中包含公鑰)傳送一份給客戶端。
  3. 客戶端的瀏覽器與Web服務器開始協(xié)商SSL連接的安全等級瞬欧,也就是信息加密的等級贷屎。
  4. 客戶端的瀏覽器根據(jù)雙方同意的安全等級,建立會話密鑰艘虎,然后利用網(wǎng)站的公鑰將會話密鑰加密唉侄,并傳送給網(wǎng)站。
  5. Web服務器利用自己的私鑰解密出會話密鑰野建。
  6. Web服務器利用會話密鑰加密與客戶端之間的通信属划。

基本流程圖如下:

Https.png

另外,假如為了安全保密候生,將一個網(wǎng)站所有的Web應用都啟用SSL技術來加密同眯,并使用Https協(xié)議進行傳輸,那么該網(wǎng)站的性能和效率會降低唯鸭,而且沒有這個必要须蜗,因為一般來說并不是所有數(shù)據(jù)都要求那么高的安全保密級別。我們只需對那些涉及機密數(shù)據(jù)的交互處理使用Https協(xié)議目溉,這樣就做到魚與熊掌兼得明肮。

Https在Android的使用——HttpsURLConnection

在Android領域,如何建立一個可靠的Https協(xié)議鏈接呢缭付?Android是基于Java進行編程的柿估,常見的Http協(xié)議建立方式有Apache的HttpClient和Sun公司提供的HttpURLConnection。不過陷猫,從API19開始官份,Google官方已經(jīng)推薦Android開發(fā)者使用HttpURLConnection來進行網(wǎng)絡連接只厘,當然,為了更方便的使用Http舅巷,很多開源庫也是提供了許多方便的功能羔味,比如Volley、OKHttp等钠右。

但是赋元,萬變不離其宗,基本流程都與HttpsURLConnection連接相似飒房。這里我就主要分享一下關于HttpsURLConnection的使用心得搁凸。

首先,明確其繼承關系狠毯。

HttpsURLConnection -> HttpURLConnection -> URLConnection

從這個繼承關系可以看出Https其實就是Http的延伸护糖,同時也是一種URLConnection的實現(xiàn)。

URLConnection是abstract類型嚼松,它是所有端到URL連接的一個父類嫡良,其實例可以用來讀寫URL的資源。要建立一個這樣的URL連接需要幾個步驟:

  1. openConnection:建立對應URL的連接
  2. 設置參數(shù)和請求屬性
  3. connection:發(fā)起實質(zhì)的鏈接
  4. 獲取請求頭信息和請求內(nèi)容

其實献酗,HttpURLConnection建立連接也就是遵循這一流程寝受。下面給出一個基本的Http連接建立的實例:

URL url = new URL("http://www.baidu.com/");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
try {
    InputStream in = new BufferedInputStream(urlConnection.getInputStream());
    readStream(in);
} finally {
    urlConnection.disconnect();
}

總結一下,基本是這幾個步驟:

  1. 通過調(diào)用URL.openConnection()獲取一個HttpURLConnection實例
  2. 設置相應請求頭信息
  3. 設置上傳的請求體(這是可選項)setDoOutput(true)
  4. 讀取返回信息罕偎,消息頭包括消息體類型很澄、長度、Cookie等颜及,用getInputStream()獲取消息體
  5. 讀完信息后甩苛,斷開連接disconnect()

熟悉了HttpsURLConnection的父類,那么Https的連接就很好建立了俏站。從前面的基礎知識讯蒲,我們可以知道,在Http的基礎上增加TLS/SSL的校驗乾翔,就可以得到Https了。

URL.openConnection()打開一個協(xié)議為Https的Url施戴,并返回一個HttpsURLConnection的實例反浓,其余的設置與Http一模一樣,其實就可以建立一個默認的Https連接了赞哗。這是因為在Android默認的機制中已經(jīng)幫我們處理好了HostNameVarifySSLSocketFactory這兩個類雷则,并且很友好地允許開發(fā)者重寫這兩個函數(shù),配置符合自己業(yè)務特點的校驗機制(后面會有具體應用)肪笋。

另外月劈,Android默認使用了X509TrustManager來解析證書鏈度迂,這個是標準權威機構的證書管理工具。在HTTPS的證書未經(jīng)權威機構認證的情況下猜揪,也要訪問HTTPS站點的兩種方法惭墓,一種方法是把該證書導入到Java的TrustStore文件中,另一種是自己實現(xiàn)并覆蓋缺省的X509證書信任管理器類而姐。

HttpDNS在Https的解決方案

什么是HttpDNS腊凶?HttpDNS使用Http協(xié)議進行域名解析,代替現(xiàn)有基于UDP的DNS協(xié)議拴念,域名解析請求直接發(fā)送到HttpDNS服務器钧萍,從而繞過運營商的Local DNS,能夠避免Local DNS造成的域名劫持問題和調(diào)度不精準問題政鼠。目前风瘦,比較有名的就是阿里云的HttpDNS解析服務了,同時公般,其它各大公司也有對應的域名解析服務万搔。但是,將HttpDNS應用到HttpDNS時俐载,就出現(xiàn)一些棘手的問題了蟹略。

問題背景是這樣的:用HttpDNS來進行Https的連接,客戶端需要驗證服務端下發(fā)的證書遏佣,驗證過程有兩個關鍵:

  1. 本地保存的根證書解開服務器發(fā)送的證書鏈挖炬,確認服務端下發(fā)的證書是由可信任的機構頒發(fā)的。
  2. 客戶端需要檢查證書的domain域和擴展域状婶,看是否包含本次請求的host意敛,即發(fā)送證書的是不是我的請求方。

上述兩點都校驗通過膛虫,就證明當前的服務端是可信任的草姻,否則就是不可信任,應當中斷當前連接稍刀。

當客戶端使用HttpDNS解析域名時撩独,請求URL中的host會被替換成HttpDNS解析出來的IP,所以在證書驗證的第2步账月,會出現(xiàn)domain不匹配的情況综膀,導致SSL/TLS握手不成功。因此局齿,針對“domain不匹配”問題剧劝,需要hook證書校驗過程中第2步,即HostNameVerify抓歼,將IP直接替換成原來的域名讥此,再執(zhí)行證書驗證拢锹。

/*
 * 使用HttpDNS在https的情況下的Demo
 * 適用于Java和Android
 */
private void connectHttps() {
    try {
        String originalUrl = "https://m.baidu.com/";
        URL url = new URL(originalUrl);
        connection = (HttpsURLConnection) url.openConnection();
        // 獲取IP Host地址
        String ip = getIpHost(url.getHost());
        if (ip != null) {
            // 進行URL替換和HOST頭設置
            String newUrl = originalUrl.replaceFirst(url.getHost(), ip);
            connection = (HttpsURLConnection) new URL(newUrl).openConnection();
            // 設置HTTP請求頭Host域
            connection.setRequestProperty("Host", url.getHost());
        }
        final String urlHost = connection.getURL().getHost();
        connection.setHostnameVerifier(new HostnameVerifier() {
            // 為解決HTTPDNS中,session攜帶的Host和IP切換后的Host不一致導致握手失敗
            @Override
            public boolean verify(String hostname, SSLSession session) {
                String host = connection.getRequestProperty("Host");
                boolean isHostNameVerify = HttpsURLConnection.getDefaultHostnameVerifier().verify(host, session);
                if (isHostNameVerify) {
                    // 判斷IP來源和Session的IP一致后萄喳,強制將Host信息賦值到Session中
                    if (!host.equals(session.getPeerHost()) && !urlHost.equals(session.getPeerHost())) {
                        return false;
                    }
                }
                return isHostNameVerify;
            }
        });
        DataInputStream dis = new DataInputStream(connection.getInputStream());
        int len;
        byte[] buff = new byte[4096];
        StringBuilder response = new StringBuilder();
        while ((len = dis.read(buff)) != -1) {
            response.append(new String(buff, 0, len));
        }
        Log.d(TAG, "Response: " + response.toString());
    } catch (Exception e) {
        e.printStackTrace();
    } finally {

    }
}

只有這樣處理卒稳,才能真正使用上HttpDNS服務,相關介紹也可以去阿里云服務的官網(wǎng)上進行查看取胎。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末展哭,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子闻蛀,更是在濱河造成了極大的恐慌匪傍,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,252評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件觉痛,死亡現(xiàn)場離奇詭異役衡,居然都是意外死亡戈次,警方通過查閱死者的電腦和手機蘑志,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來雄嚣,“玉大人俐芯,你說我怎么就攤上這事棵介。” “怎么了吧史?”我有些...
    開封第一講書人閱讀 168,814評論 0 361
  • 文/不壞的土叔 我叫張陵邮辽,是天一觀的道長。 經(jīng)常有香客問我贸营,道長吨述,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,869評論 1 299
  • 正文 為了忘掉前任钞脂,我火速辦了婚禮揣云,結果婚禮上,老公的妹妹穿的比我還像新娘冰啃。我一直安慰自己邓夕,他們只是感情好,可當我...
    茶點故事閱讀 68,888評論 6 398
  • 文/花漫 我一把揭開白布阎毅。 她就那樣靜靜地躺著焚刚,像睡著了一般。 火紅的嫁衣襯著肌膚如雪净薛。 梳的紋絲不亂的頭發(fā)上汪榔,一...
    開封第一講書人閱讀 52,475評論 1 312
  • 那天蒲拉,我揣著相機與錄音肃拜,去河邊找鬼痴腌。 笑死,一個胖子當著我的面吹牛燃领,可吹牛的內(nèi)容都是我干的士聪。 我是一名探鬼主播,決...
    沈念sama閱讀 41,010評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼猛蔽,長吁一口氣:“原來是場噩夢啊……” “哼剥悟!你這毒婦竟也來了?” 一聲冷哼從身側響起曼库,我...
    開封第一講書人閱讀 39,924評論 0 277
  • 序言:老撾萬榮一對情侶失蹤区岗,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后毁枯,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體慈缔,經(jīng)...
    沈念sama閱讀 46,469評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,552評論 3 342
  • 正文 我和宋清朗相戀三年种玛,在試婚紗的時候發(fā)現(xiàn)自己被綠了藐鹤。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,680評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡赂韵,死狀恐怖娱节,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情祭示,我是刑警寧澤肄满,帶...
    沈念sama閱讀 36,362評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站绍移,受9級特大地震影響悄窃,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蹂窖,卻給世界環(huán)境...
    茶點故事閱讀 42,037評論 3 335
  • 文/蒙蒙 一轧抗、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧瞬测,春花似錦横媚、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至孝宗,卻和暖如春穷躁,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背因妇。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評論 1 274
  • 我被黑心中介騙來泰國打工问潭, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留猿诸,地道東北人。 一個月前我還...
    沈念sama閱讀 49,099評論 3 378
  • 正文 我出身青樓狡忙,卻偏偏與公主長得像梳虽,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子灾茁,可洞房花燭夜當晚...
    茶點故事閱讀 45,691評論 2 361

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理窜觉,服務發(fā)現(xiàn),斷路器北专,智...
    卡卡羅2017閱讀 134,711評論 18 139
  • 原文地址 http://blog.csdn.net/u012409247/article/details/4985...
    0fbf551ff6fb閱讀 3,524評論 0 13
  • 本文摘自 騰訊bugly 的文章《全站 HTTPS 來了》,內(nèi)容有修改录粱。 大家在使用百度腻格、谷歌或淘寶的時候,是否注...
    bnotes閱讀 3,658評論 1 9
  • 蒲公英很別致啥繁,很神奇菜职,這是從小到大一個固有的認知。 每每在田間地頭看見它旗闽,就如同在河蚌中發(fā)現(xiàn)了珍珠一般酬核,如獲至寶,...
    A于航閱讀 671評論 0 1
  • 深夜襲來适室,毫無睡意嫡意,想念的人遠在天邊,聽著窗外的聲聲犬吠和空調(diào)呼呼的風聲捣辆,少有的失眠和頹廢蔬螟,都在黑暗中匍匐,然后在...
    思南慕北閱讀 386評論 0 0