HTTPS 是創建在密碼學基礎之上的一種安全通訊協議,嚴格來講是基於 HTTP 協議和 SSL/TLS 的組合。理解 HTTPS 以前有必要弄清楚一些密碼學的相關基礎概念,好比:明文、密文、密碼、密鑰、對稱加密、非對稱加密、信息摘要、數字簽名、數字證書。接下來我會逐個解釋這些術語,文章裏面提到的『數據』、『消息』都是同一個概念,表示用戶之間通訊的內容載體,此外文章中提到了如下幾個角色:html
密碼學中的「密碼」術語與網站登陸時用的密碼(password)是不同的概念,password 翻譯過來實際上是「口令」,它是用於認證用途的一組文本字符串。git
而密碼學中的密碼(cipher)是一套算法(algorithm),這套算法用於對消息進行加密和解密,從明文到密文的過程稱之爲加密,密文反過來生成明文稱之爲解密,加密算法與解密算法合在一塊兒稱爲密碼算法。程序員
密鑰(key)是在使用密碼算法過程當中輸入的一段參數。同一個明文在相同的密碼算法和不一樣的密鑰計算下會產生不一樣的密文。不少知名的密碼算法都是公開的,密鑰纔是決定密文是否安全的重要參數,一般密鑰越長,破解的難度越大,好比一個8位的密鑰最多有256種狀況,使用窮舉法,能很是輕易的破解。根據密鑰的使用方法,密碼可分爲對稱加密和公鑰加密。算法
對稱密鑰(Symmetric-key algorithm)又稱爲共享密鑰加密,加密和解密使用相同的密鑰。常見的對稱加密算法有DES、3DES、AES、RC五、RC6。對稱密鑰的優勢是計算速度快,可是它有缺點,接收者須要發送者告知密鑰才能解密,所以密鑰如何安全的發送給接收者成爲了一個問題。安全
Alice 給 Bob 發送數據時,把數據用對稱加密後發送給 Bob,發送過程當中因爲對數據進行了加密,所以即便有人竊取了數據也無法破解,由於它不知道密鑰是什麼。可是一樣的問題是 Bob 收到數據後也束手無策,由於它也不知道密鑰是什麼,那麼 Alice 是否是能夠把數據和密鑰一同發給 Bob 呢。固然不行,一旦把密鑰和密鑰一塊兒發送的話,那就跟發送明文沒什麼區別了,由於一旦有人把密鑰和數據同時獲取了,密文就破解了。因此對稱加密的密鑰配是個問題。如何解決呢,公鑰加密是一個辦法。markdown
公開密鑰加密(public-key cryptography)簡稱公鑰加密,這套密碼算法包含配對的密鑰對,分爲加密密鑰和解密密鑰。發送者用加密密鑰進行加密,接收者用解密密鑰進行解密。加密密鑰是公開的,任何人均可以獲取,所以加密密鑰又稱爲公鑰(public key),解密密鑰不能公開,只能本身使用,所以它又稱爲私鑰(private key)。常見的公鑰加密算法有 RSA。網絡
仍是以Alice 給 Bob 發送數據爲例,公鑰加密算法由接收者 Bob 發起併發
雖然公鑰加密解決了密鑰配送的問題,可是你無法確認公鑰是否是合法的,Bob 發送的公鑰你不能確定真的是 Bob 發的,由於也有可能在 Bob 把公鑰發送給 Alice 的過程當中出現中間人攻擊,把真實的公鑰掉包替換。而對於 Alice 來講徹底不知。還有一個缺點是它的運行速度比對稱加密慢不少。函數
消息摘要(message digest)函數是一種用於判斷數據完整性的算法,也稱爲散列函數或哈希函數,函數返回的值叫散列值,散列值又稱爲消息摘要或者指紋(fingerprint)。這種算法是一個不可逆的算法,所以你無法經過消息摘要反向推倒出消息是什麼。因此它也稱爲單向散列函數。下載軟件時如何肯定是官方提供的完整版呢,若是有中間人在軟件裏面嵌入了病毒,你也不得而知。因此咱們可使用散列函數對消息進行運算,生成散列值,一般軟件提供方會同時提供軟件的下載地址和軟件的散列值,用戶把軟件下載後在本地用相同的散列算法計算出散列值,與官方提供的散列值對比,若是相同,說明該軟件是完成的,不然就是被人修改過了。經常使用的散列算法有MD五、SHA。oop
下載 Eclipse 時,官方網站同時提供了軟件地址和消息摘要
散列函數能夠保證數據的完整性,識別出數據是否被篡改,但它並不能識別出數據是否是假裝的,由於中間人能夠把數據和消息摘要同時替換,數據雖然是完整的,但真實數據被掉包了,接收者收到的並非發送者發的,而是中間人的。消息認證是解決數據真實性的辦法。認證使用的技術有消息認證碼和數字簽名。
消息認證碼(message authentication code)是一種能夠確認消息完整性並進行認證(消息認證是指確認消息來自正確的發送者)的技術,簡稱 MAC。消息認證碼能夠簡單理解爲一種與密鑰相關的單向散列函數。
Alice 給 Bob 發送消息前,先把共享密鑰(key)發送給 Bob,Alice 把消息計算出 MAC 值,連同消息一塊兒發送給 Bob,Bob 接收到消息和 MAC 值後,與本地計算獲得 MAC 值對比,若是二者相同,就說明消息是完整的,並且能夠肯定是 Alice 發送的,沒有中間人僞造。不過,消息認證碼一樣會遇到對稱加密的密鑰配送問題,所以解決密鑰配送問題仍是要採用公鑰加密的方式。
此外,消息認證碼還有一個沒法解決的問題,Bob 雖然能夠識別出消息的篡改和假裝,可是 Alice 能夠否定說:「我沒發消息,應該是 Bob 的密鑰被 Attacker 盜取了,這是 Attacker 發的吧」。Alice 這麼說你還真沒什麼能夠反駁的,那麼如何防止 Alice 不認可呢,數字簽名能夠實現。
Alice 發郵件找 Bob 借1萬錢,由於郵件能夠被人篡改(改爲10萬),也能夠被僞造(Alice 根本就沒發郵件,而是 Attacker 僞造 Alice 在發郵件),Alice 借了錢以後還能夠不認可(不是我借的,我沒有簽名啊)。
消息認證碼能夠解決篡改和僞造的問題,Alice 不認可本身借了錢時,Bob 去找第三方機構作公正,即便這樣,公正方也無法判斷 Alice 有沒有真的借錢,由於他們倆共享了密鑰,也就是說兩個均可以計算出正確的 MAC 值,Bob 說:「明明你發的消息和 MAC 值和我本身生成的 MAC 值同樣,確定是你發的消息」,Alice 說:「你把密鑰透露給了其餘人,是他發的郵件,你找他去吧」。Alice 矢口否定。
數字簽名(Digital Signature)就能夠解決否定的問題,發送消息時,Alice 和 Bob 使用不一樣的密鑰,把公鑰加密算法反過來使用,發送者 Alice 使用私鑰對消息進行簽名,並且只能是擁有私鑰的 Alice 能夠對消息簽名,Bob 用配對的公鑰去驗證簽名,第三方機構也能夠用公鑰驗證簽名,若是驗證經過,說明消息必定是 Alice 發送的,抵賴也不行,由於你只有 Alice 能夠生成簽名。這就防止了否定的問題。
它的流程是:
第一步:發送者 Alice 把消息哈希函數處理生成消息摘要,摘要信息使用私鑰加密以後生成簽名,連同消息一塊兒發送給接收者 Bob。
第二步:數據通過網絡傳輸,Bob收到數據後,把簽名和消息分別提取出來。
第三步:對簽名進行驗證,驗證的過程是先把消息提取出來作一樣的Hash處理,獲得消息摘要,再與 Alice 傳過來的簽名用公鑰解密,若是二者相等,就表示簽名驗證成功,不然驗證失敗,表示不是 Alice發的。
公鑰密碼在數字簽名技術裏面扮演舉足輕重的角色,可是如何保證公鑰是合法的呢,若是是遭到中間人攻擊,掉包怎麼辦?這個時候公鑰就應該交給一個第三方權威機構來管理,這個機構就是認證機構(Certification Authority)CA,CA 把用戶的姓名、組織、郵箱地址等我的信息收集起來,還有此人的公鑰,並由 CA 提供數字簽名生成公鑰證書(Public-Key Certificate)PKC,簡稱證書。
Alice 向 Bob 發送消息時,是經過 Bob 提供的公鑰加密後的數據,而 Alice 獲取的公鑰並非由 Bob 直接給的,而是由委託一個受信任的第三方機構給的。
至此,一套比較完善的數據傳輸方案就完成了。HTTPS(SSL/TLS)就是在這樣一套流程基礎之上創建起來的。
本文首發於公衆號『一個程序員的微站』(id:VTtalk),分享 Python 等技術乾貨和有溫度的內容,歡迎關注
博客地址:foofish.net/https-story…