1 概述
網絡請求方式通常分為兩種,分別是HTTP請求和HTTPS請求,其中HTTP的傳輸屬于明文傳輸,在傳輸的過程中容易被人截取并且偷窺其中的內容,而HTTPS是一種在HTTP的基礎上加了SSL/TLS層(安全套接層)的安全的超文本傳輸協議,其傳輸的內容是通過加密得到的,所以說是一種安全的傳輸
2 加密算法
說到加密算法,先來了解一下兩種常用的加密方式,分別是對稱加密和非對稱加密:
1.對稱加密:加密使用的秘鑰和解密使用的秘鑰是相同的,也就是說加密和解密都使用同一個秘鑰,加密算法是公開的,秘鑰是加密者和解密者絕對保密的
2.非對稱加密:加密使用的秘鑰和解密使用的秘鑰是不相同的,HTTPS在數字證書驗證的時候,采用的RSA密碼體制就是一種非對稱加密
RSA是一種公鑰密碼體制,現在使用非常廣泛,這個密碼體制分為三部分,公鑰、私鑰、加密算法,其中公鑰和加密算法是公布的,私鑰是自己保密的。這種機制最大的特點是,通過公鑰加密的密文只有對應的私鑰才能解密,同樣通過私鑰加密的密文也只有對應的公鑰才能解密。下面我們將會講到HTTPS是如何通過RSA這種密碼體制去驗證身份的
3 數字證書
數字證書是Https實現安全傳輸的基礎,它是由權威的CA機構頒發的,證書的主要內容有:公鑰(Public Key)、ISSUER(證書的發布機構)、Subject(證書持有者)、證書有效期、簽名算法、指紋及指紋算法
在網絡中,要想實現自己的數據能夠安全地傳輸,就必須向權威的CA機構申請數字證書,有了數字證書就相當于有了一把安全秘鑰,這里先認識一下證書是長啥樣的,之后再解析證書是如何進行安全認證的
下面是CSDN博客的證書內容:
可以看到公鑰是一串很長的2048 Bits的字符串,同時也可以看到<使用者>的內容包含了csdn.net網址,在后面驗證URL鏈接是否正確的時候用到,還有頒發者、有效期、簽名算法等等。當然還有指紋及指紋算法等其他內容,我們滾動到下面看看另一個截圖
上面展示了CSDN網站的CA證書內容,頒發者是GeoTrust,它就是傳說中的權威的CA機構了。這里特別說明一下,CA機構除了給別人頒發證書以外,它也有自己的證書,這個證書是機構自己頒發給自己的,為了區分我們稱它為根證書,根證書也有自己的公鑰和私鑰,在本文中我們稱之為根公鑰和根私鑰,根公鑰和加密算法是對外公布的,而根私鑰是CA機構自己絕對保密的。這個根證書在驗證證書的過程中起著核心的作用
哪里可以看到機構的根證書呢?
?
在受信任的根證書頒發機構中我們看到一系列的CA機構,如上面CSDN的證書的頒發者GeoTrust機構也在其中,這些權威機構的根證書都是瀏覽器預先嵌入到其系統中的,點開看看GeoTrust的根證書,可以發現頒發者和使用者都是一樣的,其中里面的公鑰就是根公鑰,在驗證數字證書的時候非常關鍵
4 證書的指紋和簽名
在解析數字證書的驗證之前,先來解析一下什么是指紋和數字簽名?
在上面的CSDN的證書中可以看到有一個叫指紋的字符串,指紋可以理解為證書身份的唯一代表,是用來保證證書的完整性的,確保證書沒有被修改過。證書在發布之前,CA機構對證書的內容用指紋算法(一般是sha1或sha256)計算得到一個hash值,這個hash值就是指紋。
(為什么用hash值作為證書的身份代表呢?首先,hash值具有不可逆性,也就是說無法通過hash值得出原來的信息內容;其次,hash值具有唯一性,即hash計算可以保證不同的內容一定得到不同的hash值)
簽名是在信息后面加上的一段數字串,可以證明該信息有沒有被修改過。數字證書在發布的時候,CA機構將證書的指紋和指紋算法通過自己的私鑰加密得到的就是證書的簽名了
先簡單闡述一下證書的指紋和簽名的作用,我們在驗證證書的時候,首 先通過機構的根公鑰去解密證書的簽名,解密成功的話會得到證書的指紋和指紋算法,指紋是一個hash值,它代表著證書的原始內容,此時再通過指紋算法計算證書內容得到另外一個hash值,如果這兩個hash值相同,則代表證書沒有被篡改過,否則就是被篡改了
5 證書的驗證
假設這是一個瀏覽器的HTTPS請求
**一:**首先瀏覽器通過URL網址去請求服務端,服務端接收到請求后,就會給瀏覽器發送一個自己的CA數字證書
**二:**瀏覽器接收到證書以后,就要開始進行驗證工作了。首先從證書中得知證書的頒發機構,然后從瀏覽器系統中去尋找此頒發機構的根證書。上面我們也看到,世界上權威CA機構的根證書都是預先嵌入到瀏覽器中的,如果在瀏覽器系中沒有找到對應的根證書,就代表此機構不是受信任的,那么就會警告無法確認證書的真假,比如以前打開12360網站就會提示,現在不會了
如果我們找到了證書頒發機構的根證書,那么就從根證書中取得那個根公鑰,用根公鑰去解密此證書的數字簽名,成功解密的話就得到證書的指紋和指紋算法,指紋是證書內容通過指紋算法計算得到的一個hash值,這里我們稱之為h1,h1代表證書的原始內容;然后用指紋算法對當前接收到的證書內容再進行一次hash計算得到另一個值h2,h2則代表當前證書的內容,如果此時h1和h2是相等的,就代表證書沒有被修改過。如果證書被篡改過,h2和h1是不可能相同的,因為hash值具有唯一性,不同內容通過hash計算得到的值是不可能相同的
有人說假如證書上的指紋是不法分子偽造的,偽造是沒有用的,因為你偽造的指紋不可能用CA機構的根私鑰去加密(根私鑰是CA機構絕對保密的),偽造者只能拿自己的秘鑰去加密這個偽造的指紋,但當我們拿機構的根公鑰去解密偽造指紋的時候是不可能成功的(加密內容只能由一對公鑰私鑰解密)
在證書沒有被修改過的基礎上,再檢查證書上的使用者的URL(比如csdn.net)和我們請求的URL是否相等,如果相等,那么就可以證明當前瀏覽器鏈接的網址也是正確的,而不是一些釣魚網之類的
但如果瀏覽器的連接被某個中間人截取了,中間人也可以發一個由權威的CA機構頒發的證書給瀏覽器,然后也可以通過證書沒有被篡改的驗證,但是在證書沒有被篡改的前提下,通過對比證書上的URL和我們請求的URL是否相同,我們還是可以判斷當前證書是不是服務器發的證書。可以這么理解,因為URL具有唯一性,所以中間人的證書的上的URL和我們的證書的URL是不可能相同的,如果中間人修改了自己證書上的URL,那么就通過不了證書沒有被篡改的驗證,所以中間人的證書也是欺騙不了我們的
到這里我們認證了三點信息:
-
證書是否為受信任的權威機構頒發的
-
證書是否被篡改
-
證書是否為服務器發過來的,而不是第三方發的
**三:**基于上面的三點信息認證都沒有問題的情況下,下一步我們有一個重要的任務就是,如何將一個對稱加密算法的秘鑰安全地發給服務器
首先隨機生成一個字符串S作為我們的秘鑰,然后通過證書公鑰加密成密文,將密文發送給服務器。因為此密文是用公鑰加密的,這是一個非對稱加密,我們知道,這個密文只有私鑰的持有者才能進行解密,在這里私鑰的持有者當然是服務器了,所以說任何第三方截取到密文也是沒用的,因為沒有對應的私鑰無法解密得到我們的密文
還有一個關鍵步驟,發送密文的時候也會對消息內容進行簽名操作。簽名上面講解過,就是對密文內容進行hash計算得到的hash值再通過公鑰或私鑰加密得到的一段數字串,這個簽名和消息內容一起發送出去。接收方收到消息以后,通過私鑰或公鑰解析出密文和簽名的hash值,同時也會對接收的消息內容進行同樣的hash計算得到另一個hash值,比對兩個hash值是否相同來判斷消息有沒有被篡改過
**四:**通過了上面的步驟以后,此時客戶端和服務端都持有了對稱加密算法的同一個秘鑰,然后兄弟倆就可以愉快地安全通信了
6 總結
數字證書的驗證有兩個重要的步驟,第一是客戶端驗證服務器發的數字證書有沒有被篡改,以及沒有被篡改的證書是否為服務器發的證書,而不是任何第三方假冒服務器發的證書;第二是客戶端將對稱加密算法的秘鑰安全地發送給服務器。這兩步都完成以后,整個HTTPS的數字證書的驗證就算是成功了。