TLS是如何保障数据传输安全(中间人攻击)
前言
前段時間和同事討論HTTPS的工作原理,當(dāng)時對這塊知識原理掌握還是靠以前看了一些博客介紹,深度不夠,正好我這位同事是密碼學(xué)專業(yè)畢業(yè)的,結(jié)合他密碼學(xué)角度對tls加解密(DH這塊)的闡述,讓我對這塊原理有了更進(jìn)一步的理解,正文開始…
今天我們討論2個話題
TLS是如何保障數(shù)據(jù)傳輸安全的
中間人攻擊的原理和攻防
什么是TLS
TLS(Transport Layer Security)是新的標(biāo)準(zhǔn),舊的標(biāo)準(zhǔn)叫SSL(Secure Sockets Layer)。
不管新舊標(biāo)準(zhǔn),他們的目的都是同一個,那就是保護(hù)數(shù)據(jù)的安全,那…究竟是怎樣算保護(hù)呢?
TLS是如何保障數(shù)據(jù)傳輸安全的
先來說一般的情況,沒有SSL的時候,客戶端和服務(wù)器,之間有一個傳輸通道是用來傳輸各種數(shù)據(jù),但!!!這個通道是透明的,也就是說,其他人可以清楚的看到客戶端和服務(wù)器到底在秘密的交換什么東西,而有了SSL之后,就是從原本的透明傳輸通道升級成了非透明的傳輸通道。這樣其他人就不容易的看到到底在傳輸什么東西了
這里不就說http和https的概念了,簡單來說就是http有了ssl就升級為https。 http 就是走的透明的通道 https 就是非透明的通道沒用https會經(jīng)常被網(wǎng)絡(luò)服務(wù)商植入廣告
沒準(zhǔn)你也遇到過,訪問某個網(wǎng)站時會被植入廣告誘導(dǎo)點擊。
這就是有因為http是明文傳輸?shù)?#xff0c;長城寬帶是知道你訪問的網(wǎng)站服務(wù)器下發(fā)的明文,自然就可以在明文中加點“東西”
達(dá)到他不可告人的目的!!
SSL是怎么起作用的
既然明文傳輸是不行的,那么把明文進(jìn)行加密傳輸唄。
就是客戶端通過加密 傳輸?shù)?服務(wù)端解密
反之
服務(wù)端加密 傳輸?shù)?客戶端解密
在到數(shù)據(jù)加密傳輸這一步之前,得首先建立安全連接通道!
SSL需要用到非對稱加密的公私鑰達(dá)到認(rèn)證并建立連接通道。
建立安全連接通道后,在利用對稱式加密對通道里所有的數(shù)據(jù)進(jìn)行加解密。
聽起來有點繞,沒關(guān)系為了要了解整個概念,必須先了解下對稱式加密和非對稱式加密
對稱式加密
假如說有一個加密的算法是【把字母往后移位k位,把位移后的結(jié)果以及k給對方】
所以當(dāng)A想要和B說HI
A首先通過這個加密方法把HI這個詞,往后移2位,就變成了JK
當(dāng)B收到位移數(shù):2 以及JK。B就可以通過位移數(shù)2 往回推成HI
這里的位移數(shù):2 就是這個對稱式加密算法的秘鑰
A和B都拿到同樣的秘鑰2,是一個對稱的概念!!
非對稱式加密
那就是A和B拿到的秘鑰是不同的。(上面的例子,A拿公鑰,B拿私鑰)
公鑰和私鑰一定是一組一對配對起來的。如果公鑰是O 私鑰是P 那么絕對OP是一組。
B先把公鑰給A B手上有私鑰
私鑰(是絕對不能外泄的) 公鑰是公開的
A 通過 B給的公鑰進(jìn)行加密變成 xx ,B收到后用自己的私鑰把xx進(jìn)行解密變成HI
如下圖:
整個SSL的建立的步驟分為3個大項目 ,粉色標(biāo)記的三個大塊
Authentication 使用非對稱加密進(jìn)行對服務(wù)器下發(fā)的證書認(rèn)證
Key Exchange (這里注意當(dāng)采用Diffie—Hellman算法會和RSA算法的不同點)
Encrypted Data Transfer 利用第二步的對稱式加密,對數(shù)據(jù)傳輸進(jìn)行加解密
想要更詳細(xì)了解圖中每一步請參閱
那些關(guān)於ssl-tls的二三事-九
注意:在公開網(wǎng)絡(luò)中比如瀏覽器訪問的站點,站點服務(wù)器不會要求客戶端發(fā)送客戶端證書,所以上圖的4和5是灰色展示
下面說一下之前我誤解的點
1. RAS和DH
都知道SSL用到了非對稱加密,包括網(wǎng)上文章:
上面文章說的其實是針對采用RSA算法的。因為DH算法中不需要,所以不會在KeyExchange這一環(huán)節(jié)中利用非對稱加密傳輸數(shù)據(jù)!
DH算法說白話一點,就是在教你如何“安全的”告訴對方密碼而不用擔(dān)心密碼被竊聽。
以下是擷取自wiki的DH流程簡圖:
上圖中,Alice和Bob通過DH算法生成秘鑰K,
其中:
g、p是2個非私密數(shù)據(jù);
a、b是私密數(shù)據(jù);
A是根據(jù):g、p、a算出來的非私密數(shù)據(jù);B是根據(jù):g、p、b算出來的非私密數(shù)據(jù);
把A從a傳到b,根據(jù)求K公式,b得到秘鑰k;a同理;
注:
p是一個大素數(shù)。p的位數(shù)決定了攻擊者破解的難度。
g則不需要很大,并且在一般的實踐中通常是2或者5。
2. RSA對稱加密算法中的秘鑰(master secret)是不經(jīng)過網(wǎng)絡(luò)傳輸?shù)?/h5>Pre-master secret (PMS)
Client’s random number
Server’s random number
Pre-master secret (PMS)
Client’s random number
Server’s random number
PMS是通過網(wǎng)絡(luò)傳輸?shù)倪@里面用到了非對稱加密!
3. 容易被忽略的重要點:客戶端驗證服務(wù)端證書也用到了非對稱加密
一般我們會給域名申請證書,最終的證書是最終用CA機構(gòu)的Root根證書簽發(fā)的。
每一次簽發(fā)的證書,都是自己的私鑰做了簽名,并放在證書里。
由于CA機構(gòu)也會用Root根證書簽發(fā)一些中間證書,再由中間證書簽發(fā)的證書去簽名生成你要申請的證書.
如下圖:
服務(wù)端下發(fā)也是下發(fā)一個證書鏈的結(jié)構(gòu),瀏覽器拿到后去一步步驗證。但光有證書鏈,客戶端是不能完成證書校驗的,必須有一張根證書才能迭代完成簽名認(rèn)證,也就是說客戶端必須信任根證書才能構(gòu)建信任基礎(chǔ),那么根證書在哪兒呢?
瀏覽器用的[可信任證書庫],
在 windows 平臺中,微軟有專門的根證書庫。
在 Linux 平臺中,軟件和服務(wù)一般使用 NSS 根證書庫。
在蘋果平臺中,也有專門的根證書庫。
在windows操作系統(tǒng)中 打開cmd 輸入 certmgr 就可以打開
瀏覽器在收到server端發(fā)來的ssl證書信息,拿到證書后驗證其數(shù)字簽名。具體就是,根據(jù)證書上寫的CA簽發(fā)機構(gòu),在瀏覽器內(nèi)置的根證書里找到對應(yīng)的公鑰,用此公鑰解開數(shù)字簽名,得到摘要(digest,證書內(nèi)容的hash值),據(jù)此驗證證書的合法性。
總之一句話,CA就是神一樣的存在,如果你信任神,你就應(yīng)該信任這些CA。
中間人攻擊(MITM )
中間人攻擊,就是中間卡了一個人幫你和服務(wù)器進(jìn)行數(shù)據(jù)交換。
這樣就代表傳輸?shù)乃袛?shù)據(jù)都被這個中間人看光光。
為什么我都用SSL了。不應(yīng)該都是數(shù)據(jù)加密了嘛,中間人是如何知道的?
用Fiddler來模擬下中間人攻擊,要完成中間人攻擊需要配置
Fiddler會在證書信任中心安裝一個它的證書
然后瀏覽器通過Fddler暴露的端口來訪問目標(biāo)站點
首先看下正常的證書長啥樣的 如下圖:
中了中間人攻擊的證書是長啥樣的 ,如下圖
其實中間人的角色,就是充當(dāng)了服務(wù)器在和你建立SSL。
所以對瀏覽器來說,這個中間人就是真正的服務(wù)器,只是瀏覽器不知情而已。
但是其實瀏覽器并不會那么笨,因為如上面我們講了瀏覽器會去【可信任證書中心】去驗證。如果遇到不存在的證書,瀏覽器就會出現(xiàn)以下的提示
客戶端本身就是壞人的情況下,才會在自己的【可信任證書中心】裝一個用于中間人攻擊的證書。
有什么辦法可以防止中間人攻擊 -》 SSL Pinning
什么是SSL Pinning
SSL Pinning 也叫 Certificate Pinning
而前面有提到一個概念,公鑰私鑰是一對一配對的。
所以同一組公私鑰出來的憑證,這個憑證里面的公鑰絕對是不會變的。
而 SSL Pinning 就是要把 SSL 固定起來,這個固定就是利用公鑰的特性實現(xiàn)的。
假設(shè)有一個APP是專門訪問baidu.com的
baidu.com證書里面的公鑰是O的話,而我app里面的代碼,已經(jīng)有預(yù)先寫好O這個公鑰,
所以當(dāng)我的app瀏覽 baidu.com的時候,取得證書里面的公鑰O
拿這個公鑰O和代碼寫的O對比是否一致。如果不一致就拒絕。
為啥是中間人攻擊的話,那么這2個O肯定不一致!
驗證一下就知道了,下面這段腳本可以從服務(wù)端下發(fā)的證書拿到公鑰
分別測試下 正常情況和中間人攻擊的情況
正常情況
#!/bin/bash certs=`openssl s_client -connect $1:443 -servername $1 -showcerts </dev/null 2>/dev/null | sed -n '/Certificate chain/,/Server certificate/p'` rest=$certs while [[ "$rest" =~ '-----BEGIN CERTIFICATE-----' ]] docert="${rest%%-----END CERTIFICATE-----*}-----END CERTIFICATE-----"rest=${rest#*-----END CERTIFICATE-----}echo `echo "$cert" | grep 's:' | sed 's/.*s:\(.*\)/\1/'`echo "$cert" | openssl x509 -pubkey -noout | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -binary | openssl enc -base64 done百度的CA證書是一個證書鏈,如下圖,分別是
//頒發(fā)者是 GlobalSign Organization Validation CA 9ncsiOH9INfRO1dZosXOLZck/Z+/ikYsRl0e+iOUmiw=//頒發(fā)者是 DigiCert Inc BbkOPUFIMuqBj5SBjChDvpb1ZCdk3b9ZNDWOnKRB/bo=中間人攻擊情況
需要設(shè)置 -proxy 去模擬
#!/bin/bash certs=`openssl s_client -proxy 127.0.0.1:8888 -connect $1:443 -servername $1 -showcerts </dev/null 2>/dev/null | sed -n '/Certificate chain/,/Server certificate/p'` rest=$certs while [[ "$rest" =~ '-----BEGIN CERTIFICATE-----' ]] docert="${rest%%-----END CERTIFICATE-----*}-----END CERTIFICATE-----"rest=${rest#*-----END CERTIFICATE-----}echo `echo "$cert" | grep 's:' | sed 's/.*s:\(.*\)/\1/'`echo "$cert" | openssl x509 -pubkey -noout | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -binary | openssl enc -base64 done客戶端如何用代碼去實現(xiàn)SSL Pinning
CertificatePinner certPinner = new CertificatePinner.Builder().add("baidu.com","sha256/9ncsiOH9INfRO1dZosXOLZck/Z+/ikYsRl0e+iOUmiw=").build();OkHttpClient okHttpClient = new OkHttpClient.Builder().certificatePinner(certPinner).build();我是正東,學(xué)的越多不知道也越多。如果決定去深究一個東西, 一定要完全搞懂, 并認(rèn)真總結(jié)一篇博客讓以后能在短時間拾起來 ( 因為不搞懂你很難寫一篇半年后還能理解的博客 )
總結(jié)
以上是生活随笔為你收集整理的TLS是如何保障数据传输安全(中间人攻击)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C#序列化与反序列化详解
- 下一篇: 记一次 .NET 某外贸Web站 内存泄