為什么需要加密?
因為http的內(nèi)容是明文傳輸?shù)奈錾海魑臄?shù)據(jù)會經(jīng)過中間代理服務(wù)器、路由器蔑穴、wifi熱點忠寻、通信服務(wù)運營商等多個物理節(jié)點,如果信息在傳輸過程中被劫持存和,傳輸?shù)膬?nèi)容就完全暴露了奕剃,他還可以篡改傳輸?shù)男畔⑶也槐浑p方察覺,這就是中間人攻擊捐腿。所以我們才需要對信息進(jìn)行加密纵朋。最簡單容易理解的就是對稱加密 。
什么是對稱加密茄袖?
就是有一個密鑰操软,它可以對一段內(nèi)容加密,加密后只能用它才能解密看到原本的內(nèi)容宪祥,和我們?nèi)粘I钪杏玫蔫€匙作用差不多聂薪。
用對稱加密可行嗎?
如果通信雙方都各自持有同一個密鑰蝗羊,且沒有別人知道胆建,這兩方的通信安全當(dāng)然是可以被保證的(除非密鑰被破解)。
然而最大的問題就是這個密鑰怎么讓傳輸?shù)碾p方知曉肘交,同時不被別人知道。如果由服務(wù)器生成一個密鑰并傳輸給瀏覽器扑馁,那這個傳輸過程中密鑰被別人劫持弄到手了怎么辦涯呻?之后他就能用密鑰解開雙方傳輸?shù)娜魏蝺?nèi)容了凉驻,所以這么做當(dāng)然不行。
換種思路复罐?試想一下涝登,如果瀏覽器內(nèi)部就預(yù)存了網(wǎng)站A的密鑰,且可以確保除了瀏覽器和網(wǎng)站A效诅,不會有任何外人知道該密鑰胀滚,那理論上用對稱加密是可以的,這樣瀏覽器只要預(yù)存好世界上所有HTTPS網(wǎng)站的密鑰就行啦乱投!這么做顯然不現(xiàn)實咽笼。
怎么辦?所以我們就需要神奇的非對稱加密
什么是非對稱加密戚炫?
有兩把密鑰剑刑,通常一把叫做公鑰、一把叫做私鑰双肤,用公鑰加密的內(nèi)容必須用私鑰才能解開施掏,同樣,私鑰加密的內(nèi)容只有公鑰能解開茅糜。
用非對稱加密可行嗎七芭?
鑒于非對稱加密的機(jī)制,我們可能會有這種思路:服務(wù)器先把公鑰直接明文傳輸給瀏覽器蔑赘,之后瀏覽器向服務(wù)器傳數(shù)據(jù)前都先用這個公鑰加密好再傳狸驳,這條數(shù)據(jù)的安全似乎可以保障了!因為只有服務(wù)器有相應(yīng)的私鑰能解開這條數(shù)據(jù)米死。
然而由服務(wù)器到瀏覽器的這條路怎么保障安全锌历?如果服務(wù)器用它的的私鑰加密數(shù)據(jù)傳給瀏覽器,那么瀏覽器用公鑰可以解密它峦筒,而這個公鑰是一開始通過明文傳輸給瀏覽器的究西,這個公鑰被誰劫持到的話,他也能用該公鑰解密服務(wù)器傳來的信息了物喷。所以目前似乎只能保證由瀏覽器向服務(wù)器傳輸數(shù)據(jù)時的安全性(其實仍有漏洞卤材,下文會說),那利用這點你能想到什么解決方案嗎峦失?
改良的非對稱加密方案扇丛,似乎可以?
我們已經(jīng)理解通過一組公鑰私鑰尉辑,已經(jīng)可以保證單個方向傳輸?shù)陌踩苑怯脙山M公鑰私鑰,是不是就能保證雙向傳輸都安全了?請看下面的過程:
某網(wǎng)站擁有用于非對稱加密的公鑰A卓练、私鑰A’隘蝎;瀏覽器擁有用于非對稱加密的公鑰B、私鑰B’襟企。
瀏覽器像網(wǎng)站服務(wù)器請求嘱么,服務(wù)器把公鑰A明文給傳輸瀏覽器。
瀏覽器把公鑰B明文傳輸給服務(wù)器顽悼。
之后瀏覽器向服務(wù)器傳輸?shù)乃袞|西都用公鑰A加密曼振,服務(wù)器收到后用私鑰A’解密。由于只有服務(wù)器擁有這個私鑰A’可以解密蔚龙,所以能保證這條數(shù)據(jù)的安全冰评。
服務(wù)器向瀏覽器傳輸?shù)乃袞|西都用公鑰B加密,瀏覽器收到后用私鑰B’解密府蛇。同上也可以保證這條數(shù)據(jù)的安全集索。
的確可以!拋開這里面仍有的漏洞不談(下文會講)汇跨,HTTPS的加密卻沒使用這種方案务荆,為什么?最主要的原因是非對稱加密算法非常耗時穷遂,特別是加密解密一些較大數(shù)據(jù)的時候有些力不從心函匕,而對稱加密快很多,看來必須得用對稱加密蚪黑,那我們能不能運用非對稱加密的特性解決前面提到的對稱加密的問題盅惜?
非對稱加密+對稱加密?
既然非對稱加密耗時忌穿,非對稱加密+對稱加密結(jié)合可以嗎抒寂?而且得盡量減少非對稱加密的次數(shù)。當(dāng)然是可以的掠剑,而且非對稱加密屈芜、解密各只需用一次即可。請看一下這個過程:
某網(wǎng)站擁有用于非對稱加密的公鑰A朴译、私鑰A’
瀏覽器向網(wǎng)站服務(wù)器請求井佑,服務(wù)器把公鑰A明文給傳輸瀏覽器。
瀏覽器隨機(jī)生成一個用于對稱加密的密鑰X,用公鑰A加密后傳給服務(wù)器。
服務(wù)器拿到后用私鑰A’解密得到密鑰X拜轨。
這樣雙方就都擁有密鑰X了,且別人無法知道它盒发。之后雙方所有數(shù)據(jù)都用密鑰X加密解密例嘱。
完美!HTTPS基本就是采用了這種方案宁舰。完美蝶防?還是有漏洞的。
中間人攻擊
中間人的確無法得到瀏覽器生成的密鑰X明吩,這個密鑰本身被公鑰A加密了,只有服務(wù)器才有私鑰A’解開拿到它呀殷费!然而中間人卻完全不需要拿到密鑰A’就能干壞事了印荔。請看:
某網(wǎng)站擁有用于非對稱加密的公鑰A、私鑰A’详羡。
瀏覽器向網(wǎng)站服務(wù)器請求仍律,服務(wù)器把公鑰A明文給傳輸瀏覽器。
中間人劫持到公鑰A实柠,保存下來水泉,把數(shù)據(jù)包中的公鑰A替換成自己偽造的公鑰B(它當(dāng)然也擁有公鑰B對應(yīng)的私鑰B’)。
瀏覽器隨機(jī)生成一個用于對稱加密的密鑰X窒盐,用公鑰B(瀏覽器不知道公鑰被替換了)加密后傳給服務(wù)器草则。
中間人劫持后用私鑰B’解密得到密鑰X,再用公鑰A加密后傳給服務(wù)器蟹漓。
服務(wù)器拿到后用私鑰A’解密得到密鑰X炕横。
這樣在雙方都不會發(fā)現(xiàn)異常的情況下,中間人得到了密鑰X葡粒。根本原因是瀏覽器無法確認(rèn)自己收到的公鑰是不是網(wǎng)站自己的份殿。那么下一步就是解決下面這個問題:
如何證明瀏覽器收到的公鑰一定是該網(wǎng)站的公鑰?
現(xiàn)實生活中嗽交,如果想證明某身份證號一定是小明的卿嘲,怎么辦?看身份證夫壁。這里政府機(jī)構(gòu)起到了“公信”的作用拾枣,身份證是由它頒發(fā)的,它本身的權(quán)威可以對一個人的身份信息作出證明掌唾》徘埃互聯(lián)網(wǎng)中能不能搞這么個公信機(jī)構(gòu)呢?給網(wǎng)站頒發(fā)一個“身份證”糯彬?
數(shù)字證書
網(wǎng)站在使用HTTPS前凭语,需要向“CA機(jī)構(gòu)”申請頒發(fā)一份數(shù)字證書,數(shù)字證書里有證書持有者撩扒、證書持有者的公鑰等信息似扔,服務(wù)器把證書傳輸給瀏覽器吨些,瀏覽器從證書里取公鑰就行了,證書就如身份證一樣炒辉,可以證明“該公鑰對應(yīng)該網(wǎng)站”豪墅。然而這里又有一個顯而易見的問題了,證書本身的傳輸過程中黔寇,如何防止被篡改偶器?即如何證明證書本身的真實性?身份證有一些防偽技術(shù)缝裤,數(shù)字證書怎么防偽呢屏轰?解決這個問題我們就基本接近勝利了!
如何防止數(shù)字證書被篡改憋飞?
我們把證書內(nèi)容生成一份“簽名”霎苗,比對證書內(nèi)容和簽名是否一致就能察覺是否被篡改。這種技術(shù)就叫數(shù)字簽名:
數(shù)字簽名
這部分內(nèi)容建議看下圖并結(jié)合后面的文字理解榛做,圖中左側(cè)是數(shù)字簽名的制作過程唁盏,右側(cè)是驗證過程
數(shù)字簽名的制作過程:
CA(證書頒發(fā)機(jī)構(gòu))擁有非對稱加密的私鑰和公鑰。
CA對證書明文信息進(jìn)行hash检眯。
對hash后的值用私鑰加密厘擂,得到數(shù)字簽名。
明文和數(shù)字簽名共同組成了數(shù)字證書轰传,這樣一份數(shù)字證書就可以頒發(fā)給網(wǎng)站了驴党。
那瀏覽器拿到服務(wù)器傳來的數(shù)字證書后,如何驗證它是不是真的获茬?(有沒有被篡改港庄、掉包)
瀏覽器驗證過程
拿到證書,得到明文T恕曲,數(shù)字簽名S鹏氧。
用CA機(jī)構(gòu)的公鑰對S解密(由于是瀏覽器信任的機(jī)構(gòu),所以瀏覽器保有它的公鑰佩谣。詳情見下文)把还,得到S’。
用證書里說明的hash算法對明文T進(jìn)行hash得到T’茸俭。
比較S’是否等于T’吊履,等于則表明證書可信。
為什么這樣可以證明證書可信呢调鬓?我們來仔細(xì)想一下艇炎。
中間人有可能篡改該證書嗎?
假設(shè)中間人篡改了證書的原文腾窝,由于他沒有CA機(jī)構(gòu)的私鑰缀踪,所以無法得到此時加密后簽名居砖,無法相應(yīng)地篡改簽名。瀏覽器收到該證書后會發(fā)現(xiàn)原文和簽名解密后的值不一致驴娃,則說明證書已被篡改奏候,證書不可信,從而終止向服務(wù)器傳輸信息唇敞,防止信息泄露給中間人蔗草。
既然不可能篡改,那整個證書被掉包呢疆柔?
中間人有可能把證書掉包嗎蕉世?
假設(shè)有另一個網(wǎng)站B也拿到了CA機(jī)構(gòu)認(rèn)證的證書,它想搞垮網(wǎng)站A婆硬,想劫持網(wǎng)站A的信息。于是它成為中間人攔截到了A傳給瀏覽器的證書奸例,然后替換成自己的證書彬犯,傳給瀏覽器,之后瀏覽器就會錯誤地拿到B的證書里的公鑰了查吊,會導(dǎo)致上文提到的漏洞谐区。
其實這并不會發(fā)生,因為證書里包含了網(wǎng)站A的信息逻卖,包括域名宋列,瀏覽器把證書里的域名與自己請求的域名比對一下就知道有沒有被掉包了。
為什么制作數(shù)字簽名時需要hash一次评也?
最顯然的是性能問題炼杖,前面我們已經(jīng)說了非對稱加密效率較差,證書信息一般較長盗迟,比較耗時坤邪。而hash后得到的是固定長度的信息(比如用md5算法hash后可以得到固定的128位的值),這樣加密解密就會快很多罚缕。
還有安全上的原因
怎么證明CA機(jī)構(gòu)的公鑰是可信的艇纺?
你們可能會發(fā)現(xiàn)上文中說到CA機(jī)構(gòu)的公鑰,我?guī)缀跻还P帶過邮弹,“瀏覽器保有它的公鑰”黔衡,這是個什么保有法?怎么證明這個公鑰是否可信腌乡?
讓我們回想一下數(shù)字證書到底是干啥的盟劫?沒錯,為了證明某公鑰是可信的导饲,即“該公鑰是否對應(yīng)該網(wǎng)站/機(jī)構(gòu)等”捞高,那這個CA機(jī)構(gòu)的公鑰是不是也可以用數(shù)字證書來證明氯材?沒錯,操作系統(tǒng)硝岗、瀏覽器本身會預(yù)裝一些它們信任的根證書氢哮,如果其中有該CA機(jī)構(gòu)的根證書,那就可以拿到它對應(yīng)的可信公鑰了型檀。
實際上證書之間的認(rèn)證也可以不止一層冗尤,可以A信任B,B信任C胀溺,以此類推裂七,我們把它叫做信任鏈或數(shù)字證書鏈,也就是一連串的數(shù)字證書仓坞,由根證書為起點背零,透過層層信任,使終端實體證書的持有者可以獲得轉(zhuǎn)授的信任无埃,以證明身份徙瓶。
另外,不知你們是否遇到過網(wǎng)站訪問不了嫉称、提示要安裝證書的情況侦镇?這里安裝的就是根證書。說明瀏覽器不認(rèn)給這個網(wǎng)站頒發(fā)證書的機(jī)構(gòu)织阅,那么沒有該機(jī)構(gòu)的根證書壳繁,你就得手動下載安裝(風(fēng)險自己承擔(dān))。安裝該機(jī)構(gòu)的根證書后荔棉,你就有了它的公鑰闹炉,就可以用它驗證服務(wù)器發(fā)來的證書是否可信了。
HTTPS必須在每次請求中都要先在SSL/TLS層進(jìn)行握手傳輸密鑰嗎润樱?
這也是我當(dāng)時的困惑之一剩胁,顯然每次請求都經(jīng)歷一次密鑰傳輸過程非常耗時,那怎么達(dá)到只傳輸一次呢祥国?用session就行昵观。
服務(wù)器會為每個瀏覽器(或客戶端軟件)維護(hù)一個session ID,在TSL握手階段傳給瀏覽器舌稀,瀏覽器生成好密鑰傳給服務(wù)器后啊犬,服務(wù)器會把該密鑰存到相應(yīng)的session ID下,之后瀏覽器每次請求都會攜帶session ID壁查,服務(wù)器會根據(jù)session ID找到相應(yīng)的密鑰并進(jìn)行解密加密操作觉至,這樣就不必要每次重新制作、傳輸密鑰了睡腿!
HTTPS中的Hash算法與加密算法
對稱秘鑰常用算法:DES语御、3DES峻贮、AES、Blowfish应闯、IDEA纤控、RC5、RC6
非對稱加密算法:RSA碉纺、Elgamal船万、背包算法、Rabin骨田、D-H耿导、ECC(橢圓曲線加密算法)
HASH算法一般有:MD5,SHA1态贤,SHA256
總結(jié)
client向server發(fā)送請求https://baidu.com舱呻,然后連接到server的443端口。
服務(wù)端必須要有一套數(shù)字證書悠汽,可以自己制作狮荔,也可以向組織申請。區(qū)別就是自己頒發(fā)的證書需要客戶端驗證通過介粘,才可以繼續(xù)訪問,而使用受信任的公司申請的證書則不會彈出提示頁面晚树,這套證書其實就是一對公鑰和私鑰姻采。
傳送證書。這個證書其實就是公鑰爵憎,只是包含了很多信息慨亲,如證書的頒發(fā)機(jī)構(gòu),過期時間宝鼓、服務(wù)端的公鑰刑棵,第三方證書認(rèn)證機(jī)構(gòu)(CA)的簽名,服務(wù)端的域名信息等內(nèi)容愚铡。
客戶端解析證書蛉签。這部分工作是由客戶端的TLS來完成的,首先會驗證公鑰是否有效沥寥,比如頒發(fā)機(jī)構(gòu)碍舍,過期時間等等,如果發(fā)現(xiàn)異常邑雅,則會彈出一個警告框片橡,提示證書存在問題。如果證書沒有問題淮野,那么就生成一個隨機(jī)值(密鑰)捧书。然后用證書對該隨機(jī)值進(jìn)行加密吹泡。
傳送加密信息。這部分傳送的是用證書加密后的密鑰(隨機(jī)值)经瓷,目的就是讓服務(wù)端得到這個密鑰(隨機(jī)值)爆哑,以后客戶端和服務(wù)端的通信就可以通過這個隨機(jī)值來進(jìn)行加密解密了。
服務(wù)端加密信息了嚎。服務(wù)端用私鑰解密泪漂,得到了客戶端傳過來的密鑰(隨機(jī)值),然后把內(nèi)容通過該值進(jìn)行對稱加密歪泳。
傳輸加密后的信息萝勤。這部分信息是服務(wù)端用密鑰(隨機(jī)值)對稱加密后的信息,可以在客戶端被還原呐伞。
客戶端解密信息敌卓。客戶端用之前生成的密鑰(隨機(jī)值)解密服務(wù)端傳過來的信息伶氢,于是獲取了解密后的內(nèi)容趟径。
參考文獻(xiàn)
https://zhuanlan.zhihu.com/p/43789231
https://www.cnblogs.com/sxiszero/p/11133747.html
https://blog.csdn.net/guizaijianchic/article/details/77961418