發表日期:2016-12 文章編輯:小燈 瀏覽次數:2858
在講解本篇文章之前可以先簡單了解一下關于Https、TLS/SSL和CA證書的基礎知識
在Android設備中,一般由系統校驗服務端數字證書的合法性,用可信CA簽發的數字證書的網站才可以正常訪問,私有簽發的數字證書的網站無法訪問(需要手動安裝證書并信任)。這種作法不能抵御在用戶設備上安裝證書(將中間人服務器的證書放到設備的信任列表中,如charles的對https抓包的做法)進行中間人攻擊。如果客戶端沒有做任何主動性的防御,很可能被不法分子利用偽造CA證書進行中間人攻擊。受信任的CA(證書頒發機構)有好幾百個,任何一家受信任的CA都可以簽發任意網站的證書,這些證書在客戶端看來都是合法的。如果客戶端使用證書鎖,它會強制校驗服務端的證書,一旦發現不匹配就會禁止通信。
** 1、Certificate Pinning**
其實Certificate Pinning是OkHttp 實現的一個類似于HPKP的技術,目的是為了使客戶端可以有主動的信任CA的權利,它的工作原理就是使用預先設置的證書指紋和服務器傳過來的證書鏈中的證書指紋進行匹配,只要有任何一對指紋匹配成功,則認為是一次合法的連接,否則禁止本次鏈接
** 2、預埋證書**
把數字證書以文件或者字符串的形式寫在本地,在SSL握手的時候用本地預埋的證書和服務器傳過來的證書進行匹配,如果匹配不成功則禁止本次通信
先貼上代碼 以OkHttp為例
** 預埋證書的寫法**
首先定義一個類實現類實現X509TrustManager接口,實現對客戶端證書鏈的校驗方法和服務端證書鏈的校驗方法,不寫的話表示不做任何校驗,默認信任所有證書鏈中的證書
讀取客戶端預埋的證書
配置Client
new OkHttpClient.Builder() .sslSocketFactory(getSSLFactory(),new MyX509TrustManager).build();
妥妥的幾行代碼搞定
new OkHttpClient.Builder() .certificatePinner(new CertificatePinner.Builder() .add("b.public.com", "sha256/**********") .add("b.public.com", "sha256/**********") .add("b.public.com", "sha256/**********") .build()) .build();
兩種做法相比較之下,Certificate Pinning更為簡潔,并且也把指紋和hostname 綁定起來,這樣做的好處就是對指定的hostname所在服務器發送過來的證書指紋進行校驗,在一定程度上既控制了證書信任同時也考慮到了靈活性。而預埋證書的做法要實現相同的功能,僅僅實現上述代碼還不夠,還需要在Client配置的時候加上hostnameVerifier校驗。
** 完整代碼的實現**
String hostname = "publicobject.com"; String pinner = "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; CertificatePinner certificatePinner = new CertificatePinner.Builder() .add(hostname,pinner) .build();OkHttpClient client = OkHttpClient.Builder() .certificatePinner(certificatePinner) .build(); Request request = new Request.Builder() .url("https://" + hostname) .build(); client.newCall(request).execute();
pinner就是證書指紋,sha256表示的是哈希值得一種算法,pinner也可以是 sha1/*********** ,具體pinner要根據購買證書所支持的配置,SSL Labs這個服務通過hostname可以查看的證書指紋。
在SSL握手的時候,會檢查配置中的指紋和服務端傳過來的證書證的指紋是否相匹配,只要有一個指紋匹配,則進行下一步,否則直接拋出異常,禁止本次連接。相關源代碼實現如下:
public void check(String hostname, List<Certificate> peerCertificates) throws SSLPeerUnverifiedException { List<Pin> pins = findMatchingPins(hostname); if (pins.isEmpty()) return;if (certificateChainCleaner != null) { peerCertificates = certificateChainCleaner.clean(peerCertificates, hostname); }for (int c = 0, certsSize = peerCertificates.size(); c < certsSize; c++) { X509Certificate x509Certificate = (X509Certificate) peerCertificates.get(c);// Lazily compute the hashes for each certificate. ByteString sha1 = null; ByteString sha256 = null;for (int p = 0, pinsSize = pins.size(); p < pinsSize; p++) { Pin pin = pins.get(p); if (pin.hashAlgorithm.equals("sha256/")) { if (sha256 == null) sha256 = sha256(x509Certificate); if (pin.hash.equals(sha256)) return; // Success! } else if (pin.hashAlgorithm.equals("sha1/")) { if (sha1 == null) sha1 = sha1(x509Certificate); if (pin.hash.equals(sha1)) return; // Success! } else { throw new AssertionError(); } } }
OkHttpClient驗證證書指紋,在CertificatePinner類中有該方法的作用是確認證書中至少有一個和綁定的指紋是否匹配;如果匹配則Okhttp認為TLS握手成功,如果不匹配則失敗,并且拋出SSLPerrUnverifiedException異常。(如果沒有證書綁定,則OKHttp認為TLS握手成功)。具體調用過程和實現細節可以查看OkHttp的RealConnection這個類。
目前在網絡通信中,中間人的存在是無法杜絕的,因為中間人利用的不是漏洞,而是利用網絡協議本身的特性。只要是它又能里轉發數據包,并且實現相應的網絡協議,就可以接入到終端和服務器之間實現中間人攻擊。
在HTTPS網絡中想做中間人攻擊,必須要在握手之前接入到網絡中,一旦HTTPS握手過程結束,之后傳輸的數據完全都是加密的,解密非常的困難。想要破解加密的數據最簡單的方法就是知道瀏覽器和網站協商的那個密碼是什么,但是密碼還是在握手過程中被RSA,DSA這種非對稱加密算法加密的,不知道私鑰還沒有辦法解密,同時瀏覽器和網站之間到底使用什么加密算法來進行加密還是在握手之間協商的,而這些方法都是保存在發給瀏覽器的證書中,于是最簡單的方法就是偽造一個證書,同時要實現TLS協議,在握手開始前進行中間人攻擊。另外,HTTPS握手過程對密碼協商的驗證是很嚴格的,中間驗證數據的環節一旦有異常,瀏覽器和網站都會中斷連接,因此偽造SSL證書進行中間人攻擊目前是對HTTPS網絡最好攻擊方式,但是偽造的證書無法經過瀏覽器的受信檢查會給出提示。
更多關于各種中間人攻擊的相關知識,我推薦這篇文章,里面有各種攻擊手段和原理講解(http://www.cnblogs.com/LittleHann/p/3741907.html)
HTTPS基礎知識
TLS/SSL工作原理
TLS/SSL握手過程
CA證書介紹
日期:2018-04 瀏覽次數:6761
日期:2017-02 瀏覽次數:3435
日期:2017-09 瀏覽次數:3654
日期:2017-12 瀏覽次數:3526
日期:2018-12 瀏覽次數:4815
日期:2016-12 瀏覽次數:4582
日期:2017-07 瀏覽次數:13642
日期:2017-12 瀏覽次數:3505
日期:2018-06 瀏覽次數:4265
日期:2018-05 瀏覽次數:4442
日期:2017-12 瀏覽次數:3556
日期:2017-06 瀏覽次數:3979
日期:2018-01 瀏覽次數:3941
日期:2016-12 瀏覽次數:3908
日期:2018-08 瀏覽次數:4423
日期:2017-12 瀏覽次數:3705
日期:2016-09 瀏覽次數:6404
日期:2018-07 瀏覽次數:3205
日期:2016-12 瀏覽次數:3230
日期:2018-10 瀏覽次數:3377
日期:2018-10 瀏覽次數:3479
日期:2018-09 瀏覽次數:3577
日期:2018-02 瀏覽次數:3595
日期:2015-05 瀏覽次數:3518
日期:2018-09 瀏覽次數:3305
日期:2018-06 瀏覽次數:3433
日期:2017-02 瀏覽次數:3869
日期:2018-02 瀏覽次數:4334
日期:2018-02 瀏覽次數:4171
日期:2016-12 瀏覽次數:3571
Copyright ? 2013-2018 Tadeng NetWork Technology Co., LTD. All Rights Reserved.