關(guān)于加密
在解釋SSH过咬、SSL與HTTPS協(xié)議之前我先介紹一下非對稱加密協(xié)議。在1976年以前制妄,所有的加密都采用對稱加密掸绞,既A使用某種加密規(guī)則對信息加密,B收到信息后逆向加密規(guī)則解密數(shù)據(jù)耕捞。這通信方式產(chǎn)生了一個難以解決的問題:A如何安全的把加密規(guī)則通知B衔掸?
在1976年有兩位數(shù)學(xué)家提出了一個嶄新的非對加密的概念:
1.A生成一對兩把密鑰(公鑰和私鑰)。公鑰是公開的俺抽,任何人都可以獲得具篇,私鑰則是保密的。
2.B獲取A生成的公鑰凌埂,然后用它對信息加密驱显。
3.A得到加密后的信息,用私鑰解密瞳抓。
受這個思路的啟發(fā)埃疫,三位數(shù)學(xué)家Rivest、Shamir 和 Adleman 設(shè)計了一種具體實現(xiàn)上面描述的非對稱加密的算法孩哑,以他們?nèi)齻€人的名字命名栓霜,就是目前在計算機領(lǐng)域應(yīng)用非常廣泛的非對稱加密算法RSA加密算法。這樣網(wǎng)絡(luò)上傳輸?shù)臄?shù)據(jù)都經(jīng)過公鑰加密横蜒,然后用私鑰解密胳蛮,就算被第三方截獲也無法解密出原始數(shù)據(jù)。想深入理解非對稱加密解密的原理可以看這里丛晌。
雖然非對稱加密很安全很強大仅炊,但是它也有缺點,相對于對稱加密它計算量更大澎蛛,計算時間更長抚垄。所以在大規(guī)模數(shù)據(jù)的安全通信場景中,普遍采用非對稱加密技術(shù)來交換對稱加密密鑰谋逻,之后的通信都采用對稱加密技術(shù)加密呆馁。
SSH
維基百科中對SSH協(xié)議的定義如下
Secure Shell(縮寫為SSH),由IETF的網(wǎng)絡(luò)工作小組(Network Working Group)所制定毁兆;SSH為一項創(chuàng)建在應(yīng)用層和傳輸層基礎(chǔ)上的安全協(xié)議浙滤,為計算機上的Shell(殼層)提供安全的傳輸和使用環(huán)境。
傳統(tǒng)的網(wǎng)絡(luò)服務(wù)程序气堕,如rsh纺腊、FTP畔咧、POP和Telnet其本質(zhì)上都是不安全的;因為它們在網(wǎng)絡(luò)上用明文傳送數(shù)據(jù)摹菠、用戶帳號和用戶口令盒卸,很容易受到中間人(man-in-the-middle)攻擊方式的攻擊骗爆。就是存在另一個人或者一臺機器冒充真正的服務(wù)器接收用戶傳給服務(wù)器的數(shù)據(jù)次氨,然后再冒充用戶把數(shù)據(jù)傳給真正的服務(wù)器。
而SSH是目前較可靠摘投,專為遠程登錄會話和其他網(wǎng)絡(luò)服務(wù)提供安全性的協(xié)議煮寡。利用SSH協(xié)議可以有效防止遠程管理過程中的信息泄露問題。通過SSH可以對所有傳輸?shù)臄?shù)據(jù)進行加密犀呼,也能夠防止DNS欺騙和IP欺騙幸撕。
SSH之另一項優(yōu)點為其傳輸?shù)臄?shù)據(jù)可以是經(jīng)過壓縮的,所以可以加快傳輸?shù)乃俣韧獗邸SH有很多功能坐儿,它既可以代替Telnet,又可以為FTP宋光、POP貌矿、甚至為PPP提供一個安全的“通道”。
相信大家看了上面的段定義也是云里霧里罪佳。用最通俗的方式來解釋一下SSH逛漫。有這么一個場景:有一個服務(wù)器在互聯(lián)網(wǎng)的另一頭,你需要遠程登錄到服務(wù)器來執(zhí)行一些命令配置這臺服務(wù)器赘艳。這個時候你和服務(wù)器之間就需要有數(shù)據(jù)通信酌毡。假設(shè)客戶端叫A,服務(wù)器叫B蕾管。
要實現(xiàn)通信枷踏,最簡單的想法就是,客戶端服務(wù)器之間建立一個TCP連接掰曾,這樣你的指令就可以通過TCP連接從A傳輸?shù)紹呕寝。再仔細想想,不對婴梧,A與B之間需要通信的數(shù)據(jù)中間經(jīng)過了C下梢、D、E塞蹭、F等網(wǎng)絡(luò)路由器設(shè)備孽江,這其中任何一個路由器被黑客攻破,你們之間的通信數(shù)據(jù)就毫無保留的被別人看到番电。
所以岗屏,你需要用一個密鑰把數(shù)據(jù)加密吧辆琅。這樣A和B之間的數(shù)據(jù)就算被第三方看到,他們也不知道內(nèi)容是什么这刷⊥裱蹋可是這里又存在一個問題,A如何通知B(或者B如何通知A)它的密鑰是什么呢暇屋?要知道只要數(shù)據(jù)是在互聯(lián)網(wǎng)上傳輸似袁,就有被截獲的可能琉预。密鑰被截獲了圈膏,你就沒有秘密可言了窍育。
現(xiàn)在我們需要考慮一個安全的方式來傳輸密鑰曙强!讓我想想——非對稱加密诈嘿!
- A孽拷、B之間建立TCP連接
- B生成一對公私密鑰
- B把公鑰發(fā)送給A
- A生成一個用于加密數(shù)據(jù)的密鑰K(既我們想通知給客戶端的密鑰偎球,之后的數(shù)據(jù)通信都使用這個密鑰加密瞳秽,這個密鑰不可讓第三方知道)
- A把K用公鑰加密發(fā)送給B联予,B解密后啼县,從此A、B之間的通信數(shù)據(jù)都用K密鑰進行加密和解密沸久。
這樣假如中間的C季眷、D、E截獲了A發(fā)給B的K密鑰內(nèi)容的數(shù)據(jù)包麦向,可是這個密鑰是用B服務(wù)器生成的公鑰加密過的瘟裸,只有B服務(wù)器知道如何解密。于是我們的數(shù)據(jù)很安全了诵竭。话告。。
看起來很簡單不是嗎卵慰?一切大功告成沙郭。等等...如果黑客H埋伏在了A和B之間的某一個路由器上,他假冒B生成一對公私密鑰裳朋,然后把公鑰發(fā)送給A病线,這樣A與H之間就建成了一個加密通道,A把所有信息發(fā)送給H鲤嫡,H截獲A的信息送挑,在假冒A與B通信。如此一來暖眼,A惕耕、B之間的通信就完全暴漏給了H,而A诫肠、B卻完全不知道司澎,這就是有名的“中間人”攻擊欺缘。
為解決這個問題,SSH協(xié)議采用由人工判斷公鑰的fingerprint是否可信的方式挤安。當(dāng)使用ssh命令連接服務(wù)器時谚殊,命令行會提示如下信息:
The authenticity of host '168.30.9.213 (<no hostip for proxy command>)' can't be established.
RSA key fingerprint is 23:42:c1:e4:3f:d2:cc:37:1d:89:cb:e7:5d:be:5d:53.
Are you sure you want to continue connecting (yes/no)?
輸入yes之后才會連接到遠程服務(wù)器,同時這個信息會存儲到用戶的.ssh/known_hosts文件中蛤铜,下次再登錄的時候嫩絮,會檢查known_host文件,如果存在相同的公鑰信息昂羡,就不在提示用戶確認了絮记。
這種認證方式假設(shè)想登陸服務(wù)器的用戶已經(jīng)知道服務(wù)器公鑰(作為服務(wù)器的用戶他自然有渠道得知服務(wù)器公鑰)摔踱。fingerprint其實就代表公鑰虐先,可以看成是公鑰的一個壓縮版。有了這個步驟派敷,如果有中間人想冒充服務(wù)器B發(fā)送公鑰給A蛹批,它不可能生成一對和B生成的一樣的公私密鑰,他發(fā)送給A的公鑰必然與B服務(wù)器的不同篮愉,所以用戶就可以根據(jù)printfinger判斷所連接的服務(wù)器是否可信腐芍,有沒有被中間人冒充。
SSH的實現(xiàn)細節(jié)
上面只是粗略講解SSH的安全協(xié)議的設(shè)計思路试躏,實際上SSH通信協(xié)議在安全通信過程中分了幾個階段猪勇,每個階段又細分了幾個步驟,具體的可參看SSH原理簡介颠蕴。幾個主要階段如下:
- 協(xié)議協(xié)商階段
- 服務(wù)端認證階段
- 客戶端認證階段
- 數(shù)據(jù)傳輸階段
客戶端認證
這里我想單獨談?wù)効蛻舳苏J證泣刹,因為對于使用linux遠程登錄功能的系統(tǒng)管理員來說能有直觀感覺的也就是是這個環(huán)節(jié)了。一般我們能接觸到的的認證方式有兩種:
- 密碼認證
- Public Key認證
密碼認證很好理解犀被,就是我們在登錄遠程linux服務(wù)器的時候提供用戶名和密碼椅您?這里面稍微提示一下,在你的用戶名和密碼通過網(wǎng)絡(luò)傳輸給服務(wù)器之前寡键,已經(jīng)經(jīng)過了服務(wù)器認證協(xié)商階段掀泳,這是一個安全的加密信道已經(jīng)建立,所以你的用戶名和密碼都是加密后傳輸給服務(wù)器的西轩,保證不會被第三方截獲员舵。
每次登錄都要輸入密碼很麻煩,且密碼如果簡單的話可能還會被暴力破解藕畔。Public Key認證提供了一種更安全便捷的認證客戶端的方式马僻。這個技術(shù)也用到了非對稱加密技術(shù),由客戶端生成公私密鑰對劫流,然后將公鑰保存在服務(wù)器上巫玻。認證的過程大體如下:
- 客戶端發(fā)起一個Public Key的認證請求丛忆,并發(fā)送RSA Key的模數(shù)作為標(biāo)識符。(如果想深入了解RSA Key詳細 -->維基百科)
- 服務(wù)端檢查是否存在請求帳號的公鑰(Linux中存儲在~/.ssh/authorized_keys文件中)仍秤,以及其擁有的訪問權(quán)限熄诡。如果沒有則斷開連接
- 服務(wù)端使用對應(yīng)的公鑰對一個隨機的256位的字符串進行加密,并發(fā)送給客戶端
- 客戶端使用私鑰對字符串進行解密诗力,并將其結(jié)合session id生成一個MD5值發(fā)送給服務(wù)端凰浮。*結(jié)合session id的目的是為了避免攻擊者采用重放攻擊(replay attack)。
- 服務(wù)端采用同樣的方式生成MD5值與客戶端返回的MD5值進行比較苇本,完成對客戶端的認證袜茧。
為更廣大群眾設(shè)計的SSL與TLS
上面wiki上也有寫,SSH其實是專門為shell設(shè)計的一種通信協(xié)議瓣窄,它垮了兩個網(wǎng)絡(luò)層(傳輸層和應(yīng)用層)笛厦。通俗點講就是只有SSH客戶端,和SSH服務(wù)器端之間的通信才能使用這個協(xié)議俺夕,其他軟件服務(wù)無法使用它裳凸。但是其實我們非常需要一個通用的,建立在應(yīng)用層之下的一個傳輸層安全協(xié)議劝贸,它的目標(biāo)是建立一種對上層應(yīng)用協(xié)議透明的姨谷,不管是HTTP、FTP映九、還是電子郵件協(xié)議或其他任何應(yīng)用層協(xié)議都可以依賴的底層的可安全通信的傳輸層協(xié)議梦湘。
網(wǎng)景公司于1994年為解決上面的問題,設(shè)計了SSL(Secure Sockets Layer)協(xié)議的1.0版本件甥,但并未發(fā)布捌议,直到1996年發(fā)布SSL3.0之后,開始大規(guī)模應(yīng)用于互聯(lián)網(wǎng)服務(wù)嚼蚀〗疲可能很多人聽所過TLS(Transport Layer Security)。它相當(dāng)于是SSL協(xié)議的一個后續(xù)版本轿曙,他是SSL經(jīng)過IETF標(biāo)準(zhǔn)化之后的產(chǎn)物(詳細參考傳輸層安全協(xié)議弄捕,下文中所說的SSL協(xié)議也包括TSL)。
跟SSH相比SSL所面臨的問題要更復(fù)雜一些导帝,上面我們提到守谓,SSH協(xié)議通過人工鑒別Public Key的printfinger來判斷與之通信的服務(wù)器是否可信(不是偽裝的中間人)∧ィ可是SSL是為了整個互聯(lián)網(wǎng)上的所有客戶端與服務(wù)器之間通信而設(shè)計的斋荞,他們彼此之間不可能自己判斷通信的對方是否可信。那么如何解決這個問題呢虐秦?
在構(gòu)思解決方案之前我先講一個概念數(shù)字簽名平酿。凤优。。蜈彼。
想了一下筑辨,還是不寫了。幸逆。棍辕。 阮老師的這篇blog對數(shù)字簽名解釋的非常到位,良心推薦还绘,如果有不了解數(shù)字簽名概念的讀者楚昭,建議先看看阮老師的文章。
回到上面我們所要解決的問題拍顷,以瀏覽器和網(wǎng)站服務(wù)器之前的安全通信舉例抚太,首先瀏覽器要求和某WEB服務(wù)器建立安全的SSL連接通道,這時需要服務(wù)器的公鑰用來加密瀏覽器生成的通信密鑰菇怀,發(fā)給WEB服務(wù)器凭舶,以確定通信密鑰晌块。假如瀏覽器接受到一個公鑰爱沟,它如何知道這個公鑰確實是來自那個WEB服務(wù)器,而不是中間的某個攻擊者截獲了它的請求匆背,假扮WEB服務(wù)器給它的假密鑰呼伸?瀏覽器總不能記錄所有可信任站點的公鑰吧。
解決問題的思路是這樣的钝尸,在SSL協(xié)議中引入了一種類似公共機關(guān)(類似于我國的國家公證處括享?)的概念,就是我們熟知的CA(數(shù)字證書認證機構(gòu))珍促。它為瀏覽器發(fā)行一個叫數(shù)字證書的東西铃辖。這個東西大體上如下圖所示,其中比較重要的信息有:
- 對象的公開密鑰
- 數(shù)字簽名
有了數(shù)字證書猪叙,瀏覽器在建立SSL連接之前娇斩,并不只是簡單獲取服務(wù)器的公鑰,而從服務(wù)器獲取數(shù)字證書穴翩。數(shù)字證書里有服務(wù)器的公鑰犬第,并且有CA給這個證書簽發(fā)的簽名。這個簽名其實是證書內(nèi)容的摘要經(jīng)過CA私鑰加密生成的芒帕。這樣瀏覽器得證書內(nèi)容和摘要歉嗓,并用CA的公鑰(每個瀏覽器都存儲著一些權(quán)威CA的公鑰)對數(shù)字簽名解密,也得到證書的摘要背蟆,比對兩個摘要如果相同鉴分,說明證書是真的哮幢,且未經(jīng)過修改。信任問題就這么解決了志珍,如果上面這段話不好理解的話家浇,再次建議讀一讀阮老師的數(shù)字簽名是什么?碴裙。
其他SSL的握手钢悲,密鑰交換,加密的細節(jié)這里就不介紹了舔株,普通開發(fā)者這要懂上面我介紹的這些基本概念就可以了莺琳。
HTTPS
讀完上面內(nèi)容,理解HTTPS就簡單了载慈,它的全稱是 Hypertext Transfer Protocol Secure惭等,也稱為HTTP over TLS, HTTP over SSL,其實就客戶端與服務(wù)系之間的HTTP通信基于TLS或則SSL協(xié)議。對于HTTP協(xié)議和SSL/TLS協(xié)議本身沒有任何特殊定制办铡,因為SSL/STL本身對HTTP協(xié)議就是透明的辞做,HTTP在SSL/TLS上運作也不需要任何特殊處理。
做為網(wǎng)站管理員寡具,可能會遇到申請數(shù)字證書的任務(wù)秤茅,理解了上面的概念,申請數(shù)字證書就不那么一頭霧水了童叠,首先你要為服務(wù)器生成一對公司密鑰框喳,然后把你網(wǎng)站的信息連同你的公鑰一起發(fā)送給某個權(quán)威的CA,CA會通過某種方式認證申請人是否真的是網(wǎng)站的所有人厦坛,比如讓你在網(wǎng)站的指定路徑上傳他指定的特殊蚊子序列五垮。驗證通過就會得到證書了。
思考題
通過代理訪問HTTPS協(xié)議的網(wǎng)站杜秸,你的通信是否安全放仗?
強烈推薦《HTTP權(quán)威指南》這本書,你會驚奇的發(fā)現(xiàn)15年前寫的書撬碟,里面的內(nèi)容今天來讀不但一點都不過是诞挨,且會收獲很多。