1. 程式人生 > 實用技巧 >關於加密、證書的那些事

關於加密、證書的那些事

這是道哥的第012篇原創

關注+星標公眾號,不錯過最新文章



目錄

## 前言 在一個物聯網系統中,終端裝置在連線雲平臺(伺服器)的時候,雲平臺需要對裝置的身份進行驗證,驗證這是一個合法的裝置之後才允許接入。這看似很簡單的一句話,背後包含了很多相關的概念,例如:加密、證書、證書標準、簽名、認證機構、SSL/TLS、OpenSSL、握手等一堆容易混淆的概念。

之前我在做智慧家居專案時,每次遇到證書以及加密的問題時,都是滿大街的查資料,但是由於每次都是解決問題之後就停止下來,沒有進行完整、系統的梳理,因此對這些概念始終感覺自己都理解了,但是又說不出所以然來。

這篇文章我們就把這些概念以及相關的使用步驟進行梳理,就像聯想記憶一樣,很多分散的東西總是記不住,但是如果把這些東西按照特定的關係組織在一起,那麼記憶起來就非常容易了。

做個小遊戲:在1分鐘內記下這十個東西:茶杯、猴子、玻璃、垃圾桶、魚竿、鳥窩、和尚、汽車、醫院、飲水機。這裡可以暫停一下,看看自己的記憶力是不是不如以前了。

我們再換個記憶方法,把這十個東西以任意荒誕的邏輯聯絡在一起,比如:一隻猴子,左手拿著茶杯,右手拿著玻璃,往垃圾桶走去。在垃圾桶旁邊,看到一隻魚竿,於是它就用魚竿去戳樹上的鳥窩。鳥窩裡掉下來一個鳥蛋,正好砸在了和尚的頭上,流血了,趕緊攔下一輛汽車去醫院。到了醫院,和尚失血太多口渴了,正好看到一臺飲水機。

把這個荒誕的故事想幾遍,然後再試著把這十個東西說出來,這回是不是感覺很容易?而且連順序都不會記錯!這就是聯想記憶的魔力。

那麼學習知識也是這個道理:分散的知識是記不住的,只有梳理成體系,把相互之間的聯絡和脈絡掌握了,再去理解這些分散的點就很容易記住了。這裡的關鍵就是把這些知識點相互之間的關係掌握了,就像一張網一樣,隨便把一個知識點拎出來,都可以根據這張網把其他的知識點聯想起來。

這篇文章的內容包括:

物聯網雲平臺,是如何驗證裝置端的合法性?
SSL/TLS是什麼?有什麼作用?在哪些場合下使用?
OpenSSL是什麼?它與SSL是什麼關係?
OpenSSH又是什麼?它與OpenSSL又有什麼區別?
HTTPS中是如何利用SSL來交換祕鑰的?握手步驟是什麼?
證書是什麼?有什麼作用?在哪些場合下使用?
證書是如何得到的?它的標準格式是什麼?包含哪些內容?
認證機構是什麼?什麼是鏈式證書?
證書與SSL有什麼關係?
簽名是什麼意思?與加密是什麼關係?
什麼是單向認證?雙向認證?

另外補充一點:這篇文章只描述“是什麼”,而不會描述“為什麼”。“為什麼”的事情留給那些數學家、密碼學家來搞定就可以了。

一個典型的物聯網產品

在實際的專案中,如果用到雲平臺,一般來說選擇性就那麼幾個:國外就用亞馬遜,國內就用阿里雲,最近也碰到一些專案使用華為雲。這裡就以之前做過的一個空氣淨化器專案來舉例:

首先,亞馬遜提供了一套SDK,這個SDK中包含了一組API函式供應用程式呼叫,向雲平臺進行安全連線、收發資料。在呼叫API函式的時候,必須提供一些必要的裝置資訊,這其中最重要的就是裝置證書檔案,也就是說,證書必須要預先儲存在裝置的檔案系統中。

那麼,證書是在什麼時候被放到空氣淨化器裝置中的?當然是生產階段,看一下這個流程:

  1. 生產工具軟體執行在產線的PC機上,通過串列埠連線到空氣淨化器裝置,從裝置中讀取唯一識別碼(例如:MAC地址);
  2. 生產工具軟體上傳必要的資訊(廠商基本資訊、廠商祕鑰、空淨裝置的唯一識別碼)給AWS雲平臺,申請得到一個證書檔案;
  3. AWS雲平臺根據廠商預先在平臺上的部署程式,產生一個證書檔案,返回給生產工具軟體;
  4. 生產工具軟體把證書檔案通過串列埠傳送給空氣淨化器裝置;
  5. 空氣淨化器裝置接收到的證書檔案之後,儲存到本地的檔案系統中。

以上這個流程是在裝置生產環節完成的,這裡的描述還是屬於粗線條的,其他一些重要的資訊沒有列出來,比如:AWS後臺如何產生證書、在連線階段後臺是如何通過證書來驗證裝置的合法性的、廠商的祕鑰是如何工作的等等,這些問題等到這邊文章的末尾就自然明白了。

下面,就按照這些概念之間的相互關係來一步一步的梳理,每一個概念是按照相互之間的關係來逐步引入的,因此建議按照順序來理解。

資料加密

明文傳輸的缺點

我們知道,client端與server端之間傳輸資料,要麼是明文傳輸、要麼是加密傳輸。明文傳輸的缺點顯而易見:

資料容易比第三方截獲;
第三方可以篡改資料;
第三方可能會冒充server與你進行通訊。

總之一句話:明文通訊就像裸奔一樣,任何東西都被別人看的一清二楚,惡意的第三方很容易利用明文通訊來做一些違法的事情。

所以,最好還是穿上衣服,最好還是帶密碼鎖的,這樣別人就看不到了!這就是加密傳輸。

加密傳輸

client端對傳輸的資訊進行加密,server端接收到密文後再進行解密。例如上圖中:

client想傳送字串"hello",那麼就先加密成"ifmmp",然後傳送出去;
server接收到"ifmmp",進行解密,得到"hello"。

但是示例中的加密方式太弱智了,稍微研究下就會搞明白,這裡的加密方式就是把明文字串中的每一個字元變成ascII碼錶中的下一個字。server在解密時操作相反:把每一個字元變成ascII碼錶中的前一個字元即可,只要client和server事先商量好這樣的加密和解密演算法就可以通訊了。

但是,這樣的加密方式太簡單了,惡意的第三方不會吹灰之力就可以破解出來,因此client與server之間需要更加複雜的加密演算法,這就是SSL要解決的問題,這部分內容稍後再表。

加密方式

根據是否可以把密文還原成明文,加密方式分為兩類:

可逆加密;
不可逆加密。

剛才描述的加密、解密過程("hello"->"ifmmp"->"hello")是屬於可逆加密,也就是說可以把密文還原成明文,主要應用在通訊場景中。如果一個密文不能還原成明文,就稱為不可逆加密,不可逆加密也非常重要。

可逆加密

剛才已經說到,可逆加密就是可以把密文還原成明文,只要client端和server端商量好加密演算法(例如剛才所說的利用ascII表的下一個字元)就可以達到目的,也就是說:client端的加密演算法和server端的解密演算法是一樣的,當然了這裡的演算法太簡單。

我們可以稍微複雜一點點,先定義一個固定的字串“258”,然後把明文"hello"中的每一個字元,用固定的字串進行計算:先加2,再減5,最後加8,得到加密後的字串"mjqqt",server接收到之後再執行相反操作就解密得到明文“hello”。從演算法角度看,這兩個加密方式是一樣的,但是第二種演算法利用了一個獨立的、固定的字串“258”,這個字串就叫做祕鑰,當然,實際通訊中使用的祕鑰更復雜。通訊雙方是通過演算法+祕鑰的方式來進行加密和解密。而且,通訊雙方使用的祕鑰是相同的,這就叫做對稱加密

既然存在對稱加密,那肯定就存在非對稱加密,也就是說,根據通訊雙方使用的祕鑰是否相同,可逆加密分為2種:

  1. 對稱加密;
  2. 非對稱加密。

對稱加密常用演算法有:DES、AES;非對稱加密常用演算法有:RSA、DH、ECC。

對稱加密的特點:

  1. 計算速度快;
  2. 加密強度高;
  3. 能處理的資料量大。

非對稱加密的特點:

  1. 效率低;
  2. 能處理的資料量大小有限制。

既然非對稱加密的缺點這麼明顯,那麼它有什麼作用呢?

回到剛才的通訊示例場景中:client與server需要使用同一個祕鑰“258”,那麼它們雙方應該如何協商得到這個對稱祕鑰呢?難道是使用固定的祕鑰嗎?顯然這個答案不太可能,需要通訊的裝置那麼多,不可能像網絡卡的MAC地址那樣預先分配,而且祕鑰很容易洩漏。因此,這個對稱祕鑰一般都是在通訊的剛開始的握手階段,由client與server動態的協商得到的。在這個協商的過程中,為了防止協商內容被第三方截獲,就需要使用非對稱加密來保證握手階段的資料安全性

因為握手資料只發生在通訊的剛開始階段,即使效率低一點也沒關係,安全比效率更重要

一句話:非對稱加密在通訊初始階段的協商過程中使用,用來得到一個對稱祕鑰,這個協商過程就叫做握手,在後面的HTTPS通訊過程中,我們再詳細看一下握手過程。

不可逆加密

顧名思義,不可逆加密就是說把明文加密之後得到密文,但是不能從密文還原得到明文。從術語上來說,一般不把這個加密結果稱作密文,而是稱作摘要或者指紋

不可逆加密原理:把一個任意大小的資料,經過一定的演算法,轉換成規定長度的輸出。如果資料的內容發生了一絲絲的變化,再次加密就得到另一個不同的結果,而且是大不相同。從這個角度看,是不是稱作指紋更形象一些?

不可逆加密最常用的演算法就是:MD5、SHA1。

回想一下:我們在下載一些軟體的時候,在伺服器上除了看到軟體的下載地址,一般還會看到該軟體的MD5碼。我們把軟體下載到本地之後,計算得到MD5,也就是檔案的指紋,然後把這個MD5與伺服器上公佈的MD5進行比較,如果這兩個MD5不一致,就說明下載的檔案被別人修改過。

這是glib庫的下載頁面:

補充:SHA相關知識

  1. SHA

    SHA安全雜湊演算法,由美國國家標準技術研究院釋出的一組加密函式。它是一種常用的摘要演算法,就是輸入一段資料,輸出合法的證書一個摘要資訊,包括SHA0、SHA1、SHA2等不同的版本。
  2. SHA1

    代表安全雜湊演算法1,接收輸入,輸出一個160位的雜湊值,稱作資訊摘要。在2005年之後,SHA1被認為不安全。
  3. SHA2

    SHA2指的是具有兩個不同塊大小的相似雜湊函式的族,其中包括:SHA256,SHA512。SHA256可以輸出一個256位的雜湊值,安全級別更高。

一個實際的使用場景:OTA升級

  1. 首先伺服器推送一個upgrate.json格式字串給裝置,檔案中包括:新韌體的下載地址URL,新韌體的MD5值;
  2. 裝置根據URL下載新韌體到本地;
  3. 裝置計算下載的新韌體MD5值,與upgrade.json中的MD5值進行比較;
  4. 如果這兩個MD5值一致,說明下載的韌體沒有問題,那麼就開始升級。

再來了解一下不可逆加密的特點

  1. 不可逆:除非使用窮舉等手段,原則上不存在根據密文推斷出原文的演算法;
  2. 雪崩效應:對輸入資料敏感,原始資料的極小改動會造成輸出指紋的巨大差異;
  3. 防碰撞:很難找到兩段不同的資料,輸出相同的指紋。
公鑰和私鑰

上面說到了非對稱加密,那麼就必須再補充一下私鑰和公鑰。從字面上就可以看出:它倆是一對兄弟,都是祕鑰,必須成對使用,稱作:祕鑰對。我們可以通過一些軟體工具(例如:OpenSSL)生成自己的公鑰和私鑰。

公鑰:就是公開告訴別人的;私鑰:就是自己的,作為寶貝一樣自己私藏起來,千萬不要告訴別人

公鑰和私鑰的作用有2個:

  1. 資料加密:公鑰加密,私鑰解密,用於通訊場景;
  2. 數字簽名:私鑰加密,公鑰解密,用於不可耍賴場景。

資料加密就是上面描述的非對稱加密,例如:

張三想發一個檔案給我,為了防止檔案被其他人看到,於是張三用我的公鑰對檔案進行加密,然後把加密後的檔案發給我。我拿到密文後,用我的私鑰就可以把密文還原成原始的檔案,其他人即使拿到了密文,但是沒有我的私鑰,就解不開檔案。 如下面這張圖:

數字簽名與我們日常生活中的借條上的簽名類似,一旦簽名了,就具有法律效力,不能耍賴說:這個不是我簽名,我不認。具體流程是:我寫了一個檔案,然後用我的私鑰對檔案進行加密,那麼如果以後我耍賴說:這個檔案不是我寫的,其他人就可以用我的公鑰來嘗試對加密後的檔案進行解密。如果成功解密了,就說明這個檔案一定是用我的私鑰進行加密的,而私鑰只有我才有,那就說明這個檔案一定是我寫的。如下圖:

證書

前面談到了公鑰是公開給別人的,本質上就是一段資料,那麼這段資料是以什麼樣的形式或者說以什麼樣的載體傳送給別人的呢?答案就是:證書

如何申請證書

我們以一個網站為例,瀏覽器在訪問網站的時候,在握手階段,網站會把自己的證書傳送給瀏覽器。那麼這個證書是如何產生的呢?

Step1

在網站上線之初,需要把自己的相關資訊放在一個請求檔案中(server.req),把請求檔案傳送給一個權威的認證機構。請求檔案的內容包括:

網站的域名
申請者資訊
公鑰
以及其他一些相關資訊

Step2

認證機構通過其他途徑來確定申請者是合法的。

Step3

認證機構使用某個演算法,對請求檔案server.req中的資訊進行計算,得到一個數字摘要

演算法包括:

MD5
SHA-1
SHA-256

資訊包括:

申請者的基本資訊:網站使用的加密演算法、網站使用的hash演算法;
申請者的公鑰;
認證機構的資訊:認證機構的名稱,證書到期時間。

Step4

認證機構用自己的私鑰,對Step3中得到的數字摘要進行加密,得到數字簽名(也就證書籤名)

Step5

認證機構把以上這些資訊進行彙總,得到最終的證書檔案server.crt,然後發給申請者。

最終,證書server.crt中的內容包括這幾個大類:

  1. 申請者的基本資訊:網站使用的加密演算法、網站使用的hash演算法;
  2. 申請者的公鑰;
  3. 認證機構的資訊:認證機構的名稱,證書到期時間。
  4. 認證機構的證書籤名。

如何確認證書的合法性

現在,客戶端拿到了伺服器發來的證書檔案,應該如何驗證這是一個合法的證書呢?

Step1

讀取證書中的明文資訊,包括:申請者的基本資訊,申請者的公鑰,認證機構的資訊。

Step2

瀏覽器或者作業系統中查詢這個認證機構的相關資訊,得到這個認證機構的公鑰。

補充:瀏覽器或者作業系統中,一般都會預裝一些可信任的權威認證機構的證書列表,所以能拿到認證機構的公鑰

Step3

使用認證機構相同的演算法,對Step1中的明文資訊進行計算,得到摘要1

Step4

使用認證機構的公鑰,對證書中認證機構的數字簽名進行解密,得到摘要2

Step5

比較摘要1與摘要2是否相同,如果相同,說明這個證書是合法的,也就證明當前訪問的是一個合法的伺服器

單向認證和雙向認證

上面描述的認證過程,是瀏覽器用來確認所訪問的網站是否是一個合法的網站;文章開頭所舉的例子:一個物聯網產品在連線雲平臺的時候,是雲平臺來驗證這個想連線進來的裝置是否為一個合法的裝置。

這兩個場景中都是單向認證,也就是通訊的一方來驗證另一方是否合法。那麼雙向認證就很好理解了:通訊的每一方都要認證對方是否合法。

至於如何選擇使用單向認證或者雙向認證,甚至是不使用證書(只使用使用者名稱和密碼來鑑權),這就需要根據實際的使用場景、安全等級、操作的難易程度來決定了。比如:在物聯網產品中,每一個產品都需要在生產階段把動態生成的證書燒寫到裝置中,增加了生產環節的流程和成本,為了安全性,萬萬不可偷懶。如果沒有證書來驗證,那麼黑客就可以模擬無數個裝置,頻繁的連線到雲平臺,這就存在極大的安全隱患。

認證機構

證書本質上就是一個檔案,只不過這個檔案具有特殊的一個性質:可以被證明是合法的。那麼應該如何來證明呢?這就要來說一下認證機構。

認證機構(CA: Certificate Authority)是一個權威的組織,是被國家、行業認可的權威結構,不是隨便一個機構都有資格頒發證書,不然也不叫做權威機構。只要能證明一個證書是由CA機構頒發的,我們就認為這個證書是合法的,也就是說:證書的可信任性基於信任機制。

就像銀行貸款給個人一樣,銀行在放款之前,會到徵信系統中查詢這個人的信用報告,如果徵信系統中表明這個人的信用沒有問題,銀行相信徵信系統,所以銀行就相信這個人,可以貸款給他,這是一個信任鏈的傳遞

CA認證機構就類似於徵信系統,相當於CA結構給證書進行了背書,它保證從它手裡頒發的證書都是合法有效的,那麼我們只要能證明證書是從CA認證機構頒發的,就可以認為證書是有效的

證書鏈

CA認證機構是一個樹狀的結構,最頂部的稱為根認證機構。往下層是:二級認證機構、三級認證機構...。

根認證機構給二級認證機構頒發證書,二級認證機構給三級認證結構頒發證書...。不同等級的認證機構對稽核的要求也不一樣,於是證書也分為免費的、便宜的和貴的。

你可能會問:那麼根認證機構的證書是由誰簽名的?答案是:根認證機構自己簽名的,這也叫做自簽名。因為根認證機構是由國家或者行業組織認可的,已經是一個可以信賴的權威機構,所以可以為自己簽名。

另外,我們在測試的過程中,也常常利用OpenSSL中提供的程式來產生自簽名的證書,當然,這個測試的自簽名證書只能你自己玩,因為別人不信任你

證書檔案的字尾名

剛接觸到證書概念的小夥伴,常常被眼花繚亂的字尾名所迷惑。

首先要明確一點:證書檔案的字尾名只是為了見名識意,實際上可以取任意的名字。常見的字尾名包括:

.crt:per格式的證書
.der: der格式的證書
.key:pem格式的私鑰
.pub:pem格式的公鑰
.req:申請證書時傳送給CA認證機構的請求檔案
.csr:也表示請求檔案

證書檔案的格式

所有證書內容格式有兩種:pem格式和der格式,這兩種格式的證書檔案可以相互轉換,利用OpenSSL中的程式就可以完成。

PEM格式(Privacy Enhanced Mail)

pem格式的證書內容是經過加密的文字檔案,一般是base64格式,可以用記事本來開啟一個base64格式的證書,例如下面這個證書檔案的內容:

-----BEGIN CERTIFICATE-----
MIIGbzCCBFegAwIBAgIICZftEJ0fB/wwDQYJKoZIhvcNApQELBQAwfDELMAkGA1UE
BhMCVVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQK
DA9TU0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZp
...
Nztr2Isaaz4LpMEo4mGCiGxec5mKr1w8AE9n6D91CvxR5/zL1VU1JCVC7sAtkdki
vnN1/6jEKFJvlUr5/FX04JXeomIjXTI8ciruZ6HIkbtJup1n9Zxvmr9JQcFTsP2c
bRbjaT7JD6MBidAWRCJWClR/5etTZwWwWrRCrzvIHC7WO6rCzwu69a+l7ofCKlWs
y702dmPTKEdEfwhgLx0LxJr/Aw==
-----END CERTIFICATE-----

補充:base64演算法就是把原始資料中按照每3個位元組進行拆分,3個位元組是24bit,然後把24bit分成4組,每組6bit,最後在每個6bit的簽名新增2個0,這樣得到的4組位元組碼就可以用ascII碼來表示了。

DER格式(Distinguished Encoding Rules)

der格式的證書檔案內容是經過加密的二進位制資料,也就是說檔案內容開啟後是亂碼。

X.509標準

上面說到證書中包含了必要的資訊,那麼這些資訊在檔案中並不是隨意擺放的,而是要根據固定的格式來儲存,只有這樣才能通過軟體生成或解析。
那麼這個固定的格式是由誰來規定的呢?這就是X.509標準與公共祕鑰證書

X.509是一個體系、標準,用來規定一個證書的格式標準,CA認證結構在生成證書的時候,就根據這個標準把每部分資訊寫入到證書檔案中。

X.509包括3個版本:V1, V2和V3。每一個版本中頒發證書時,必須包含下列資訊:

版本號:用來區分版本;
系列號:由CA認證機構給每一個證書分配一個唯一的數字編號;
演算法簽名識別符號:用來指定CA認證機構在頒發證書時使用的簽名演算法;
認證機構:頒發證書的機構唯一名稱;
有效期限:證書有效期(開始時間和結束時間);
主題資訊:證書持有人的基本資訊;
公鑰資訊:證書持有者的公鑰;
認證結構簽名:以確保這個證書在頒發之後沒有被篡改過;

證書格式

總之:證書的核心功能就是安全的傳遞公鑰!

OpenPGP協議/標準

加密和證書的概念介紹完了,再來了解一個行業標準:OpenPGP

OpenPGP是什麼?

OpenPGP是一種非專有協議,為加密訊息、簽名、私鑰和用於交換公鑰的證書定義了統一標準。

OpenPGP協議的實現

OpenPGP協議有2個實現

  1. PGP(Pretty Good Privacy)
  2. GPG(GNU Privacy Guard)

PGP是一個加密程式,為資料通訊提供了加密和驗證功能,通常用於簽名、加密和解密文字、電子郵件和檔案。

GPG是PGP的開源實現

OpenPGP的使用流程

Step1: 公佈自己的公鑰

每個人把自己的公鑰上傳到公鑰伺服器上(subkeys.pgp.net),然後通過交換機制,所有的公鑰伺服器最終都會包含你的公鑰,就類似域名伺服器同步域名解析資訊一樣。

由於公鑰伺服器沒有檢查機制,任何人都可以用我的名義上傳公鑰,所以沒有辦法來保證伺服器上的公鑰一定是可靠性。通常,我可以在網站上公佈一個公鑰指紋,讓其他人下載我的公鑰之後,計算一下公鑰指紋,然後與我公佈的指紋進行比對,以此來確認證書的有效性。

Step2: 獲取別人的公鑰

為了獲得別人的公鑰,可以讓對方直接發給我,也可以從公鑰伺服器上下載。為了安全起見,需要對下載的公鑰使用其他機制進行安全認證,例如剛才說的指紋。

Step3: 用於加密

用對方的公鑰加密檔案,傳送給對方,對方用他自己的私鑰進行解密。

Step4: 用於簽名

用我的私鑰進行加密,把加密後文件傳送給對方,對方用我的公鑰進行解密,只要能正確解密,就證明這個檔案的確是我加密的。

SSL/TLS

SSL全稱是Secure Socket Layer(安全套階層協議),它是一個安全協議,目的是用來為網際網路提供安全的資料傳輸。

SSL在工作過程中,就利用了前面描述的概念:對稱加密、非對稱加密、證書等。如果前面的概念都梳理清楚了,那麼理解SSL也就不成問題了。

SSL協議有1,2,3這個三個版本,TLS是SSL V3標準化之後的產物。事實上現在用的都是TLS,但是大家都習慣了SSL這個稱呼。

協議分層

SSL協議最大的優點就是與應用層無關,在SSL協議的上層,可以執行一些高層應用協議,例如:HTTP, FTP, TELNET...,也就是說這些高層協議可以透明的建立在SSL協議層之上。

握手過程

SSL使用X.509標準,握手就是指客戶端與服務端在通訊的開始階段進行鑑權和協商,最終目的是:

  1. 確認對方是合法的通訊物件;
  2. 與對方協商得到對稱加密祕鑰。

我們來一步一步梳理握手過程:

Step1

Client向Server傳送如下資訊:

隨機數1;
Client端支援的SSL版本號;
Client端支援的加密演算法列表。

Step2

Server分析接收到的資訊,返回如下資訊給Client:

隨機數2;
選擇的加密演算法;
Server證書

Step3

Client端驗證Server發來的證書是否有效,具體過程上面已經描述過。

如果驗證失敗,通訊結束
如果驗證通過,就產生隨機數3,並使用剛才的隨機數1、隨機數2,然後用選擇的演算法生成一個對稱加密祕鑰,這個祕鑰就用於後面正常的資料通訊中。

然後傳送如下資訊給Server:

隨機數3,並且用server證書中的公鑰進行加密;

此時,Cliend端的握手流程結束,因為已經達到了握手的最終目的:確認Server合法,得到對稱加密祕鑰。

Step4

Server端在接收到加密後的隨機數3時,用自己的私鑰進行解密,然後和之前的隨機數1、隨機數2一起,使用相同的演算法生成對稱加密祕鑰

至此,Server端的握手過程也就結束,下面就可以用對稱加密祕鑰來對資料進行加密了

注意:上面描述的握手過程中是單向認證,也就是Client端驗證Server是否合法的
如果需要雙向認證,那麼客戶端也應該把自己的證書傳送給Server,然後Server來驗證這個證書是否合法,確認證書合法之後才繼續執行後面面的握手流程。

HTTPS與SSL的關係

HTTPS拆開來就是:HTTP+SSL,就是在HTTP的下面增加了SSL安全傳輸協議層,在瀏覽器連線到伺服器之後,就執行上面描述的SSL握手過程。握手結束之後,雙方得到對稱加密祕鑰,在HTTP協議看來是明文傳輸資料,下面的SSL層對資料進行加密和解密。

OpenSSL

OpenSSL是什麼?

上面描述的SSL中這麼多的東西都是協議(或者稱為標準),協議只是規定了應該怎麼做,但是具體的程式碼實現應該由誰來做呢?我們在寫相關的SSL程式時好像從來沒有實現過這個協議,都是直接呼叫第三方提供的庫就達到了加密傳輸的目的。當然了,如果你實現過SSL協議,請允許我對你表示佩服,給你一萬個贊!

在程式設計領域,永遠都存在熱心腸的人!OpenSSL就是一個免費的SSL/TLS實現,就是說:OpenSSL實現了SSL/TLS協議中定義的所有功能,包括:

SSL2
SSL3
TLSv1
TLSv1.1
TLSv1.2

而且,OpenSSL是用C語言開發的,具有優秀的跨平臺特性,在Linux、Windows、BSD、MAC等平臺上可以執行。

具體來說,OpenSSL實現中,包括下面幾個功能模組

密碼演算法庫

密碼演算法庫中包括:

對稱加密演算法: AES、DES等。
非對稱加密演算法: DH、RSA、DSA、EC等。

資訊摘要演算法

資訊摘要演算法包括:MD5、SHA等。

祕鑰和證書管理

OpenSSL提供的CA應用程式就是一個小型的證書管理中心,實現了證書籤發的整個流程和證書管理的大部分機制,我們在學習的時候一般都會用OpenSSL中提供的CA程式來生成祕鑰對、自簽名等等。具體的內容包括:

證書祕鑰產生、請求產生、證書籤發、吊銷和驗證功能;
對證書的X.509標準解碼、PKCS#12/PKCS#7格式的編解碼;
提供了產生各種祕鑰對的函式;

SSL協議庫

實現了SSLv2、SSLv3、TLSv1.0協議。

應用程式

OpenSSL的應用程式是基於密碼演算法庫和SSL協議庫實現的,是非常好的OpenSSL的API函式使用範例,主要包括:祕鑰生成、證書管理、格式轉換、資料加密和簽名、SSL測試以及其他輔助配置功能

OpenSSH又是什麼?

SSH

首先說一下SSH:Secure Shell(安全外殼協議),又是一個協議,用來實現遠端登入系統,我們通常利用SSH來傳輸命令列介面和遠端執行命令。

比如:在除錯一個ARM系統時,可以通過串列埠助手連線到ARM板子上;但是更常用的除錯場景是在PC機上遠端登入到ARM系統中,執行ARM中的任何指令,這就是利用SSH來實現的。

SSH提供2種級別的安全驗證:

基於密碼;
基於祕鑰。

SSH中基於口令的安全驗證

只需要知道賬號和密碼,就可以遠端登入到系統,我們一般常用的就是這用方式。但是不能保證我正在連線的裝置就是我想連線的那臺裝置,可能會有別的伺服器冒充真正的伺服器,也就是受到“中間人”這種方式的攻擊。

當然還經常遇到另一種錯誤:在區域網中有多臺裝置,本想遠端連線到裝置A中,由於IP地址記錯了,結果遠端登入到另外一臺裝置B上了,如果你的同事也正在除錯裝置B,接下來就是悲劇發生的時刻!

SSH中基於祕鑰的安全認證

Step1

首先為自己建立一個祕鑰對,並提前把公鑰放在需要訪問的伺服器上,例如:放在賬號的家目錄中。

Step2

通過客戶端遠端登入到伺服器,把自己的公鑰發給伺服器,並請伺服器進行安全驗證。

Step3

伺服器接收到請求後,在登入賬號的家目錄下查詢公鑰,然後與接收到的公鑰進行比對。

Step4

如果比對不一致,通訊結束;如果比對一致,伺服器就用公鑰加密一段資料(challenge),併發送給客戶端。

Step5

客戶端接收到challenge,用私鑰進行解密,然後把結果發給伺服器。

Step6

伺服器把接收到的結果與Step4中的資料進行比對,如果一致則驗證通過。

SSH協議的實現

既然SSH是一個協議,那麼就一定存在對應的實現,這就是OpenSSH,它是一個免費開源的SSH實現

OpenSSH實現中,利用了OpenSSL中的加密和演算法庫函式,這就是它倆之間的關係。

總結

到這裡,與加密、證書相關的基礎概念都介紹完畢了,不知道你是否有所收穫。

如果你是初次接觸到這些東西,敬請放心,即使現在明白了,一個星期之後肯定忘記一多半了。只有經歷過幾個專案的歷練之後,才會有更深刻的理解和記憶,最後,祝您好運!


【原創宣告】

> 作者:道哥(公眾號: IOT物聯網小鎮)
> 知乎:道哥
> B站:道哥分享
> 掘金:道哥分享
> CSDN:道哥分享

如果覺得文章不錯,請轉發、分享給您的朋友。


我會把十多年嵌入式開發中的專案實戰經驗進行總結、分享,相信不會讓你失望的!

長按下圖二維碼關注,每篇文章都有乾貨。


轉載:歡迎轉載,但未經作者同意,必須保留此段宣告,必須在文章中給出原文連線。




推薦閱讀

[1] 原來gdb的底層除錯原理這麼簡單
[2] 生產者和消費者模式中的雙緩衝技術
[3] 深入LUA指令碼語言,讓你徹底明白除錯原理
[4] 一步步分析-如何用C實現面向物件程式設計