
工作或者面試過程中我們總會接觸到密碼相關(guān)的技術(shù)和問題,本篇文章是我對近期閱讀《圖解密碼技術(shù)》的總結(jié),這本書很值得推薦。那本篇文章是否適合你呢,如果下面的問題你都了解這篇文章暫時不適合你。
- 工作中你用到過哪些加密算法?
- 分組密碼的模式有哪些?(分組密碼是如何迭代的?)
- 對稱加密(共享秘鑰密碼)和非對稱加密(公鑰密碼)那個快?
- 說說混合密碼系統(tǒng)的具體實現(xiàn)?
- SSL/TLS用到哪些密碼相關(guān)技術(shù)?
- 區(qū)塊鏈用到了哪些密碼相關(guān)技術(shù)?
- 單項散列函數(shù)、消息認(rèn)證碼、數(shù)組簽名、證書分別是為了解決哪些問題?
- ......
本文章只對我認(rèn)為重要的知識點做簡單介紹和梳理,想詳細(xì)了解可以閱讀原書籍。
開始之前我們先明確一個基本的概念。
加密,是以某種特殊的算法改變原有的信息數(shù)據(jù),使得未授權(quán)的用戶即使獲得了已加密的信息,但因不知解密的方法,仍然無法了解信息的內(nèi)容。所以Hash算法并不能稱為加密算法,因為操作者本人都無法解密成原數(shù)據(jù)。
密碼技術(shù)
根據(jù)秘鑰的使用方法可以將密碼分為:對稱密碼和公鑰密碼兩種。對稱密碼(共享秘鑰密碼)是指加密和解密時使用同一秘鑰的方式;非對稱密碼(公鑰密碼)是指加密和解密時使用不同秘鑰的方式。
對稱密碼
常用的對稱密碼算法主要有DES、三重DES、AES、Rijndael、APPTagId
比特序列的異或
密碼技術(shù)中經(jīng)常會用到比特序列的異或運算xor,用符號表示⊕,a⊕b = (?a ∧ b) ∨ (a ∧?b),如果a、b兩個值不相同,則異或結(jié)果為1。如果a、b兩個值相同,異或結(jié)果為0。密碼學(xué)中用到異或運算的一個特性是:如果有比特序列a、b、c ,如果a⊕b=c則 c⊕b=a。
| 0101(a) | |
|---|---|
| ⊕ | 0011(b) |
| 結(jié)果 | 0110(c) |
逆運算:
| 0110(c) | |
|---|---|
| ⊕ | 0011(b) |
| 結(jié)果 | 0101 (a) |
有沒有發(fā)現(xiàn)什么我們把a當(dāng)做源數(shù)據(jù),b當(dāng)做秘鑰,c當(dāng)做加密后的密文,a⊕b相當(dāng)于加密。c和b異或后又變成了a。這不就是一個很簡單的對稱加密嘛。
DES
DES現(xiàn)在已經(jīng)不是一種安全的加密方法,已經(jīng)能夠被暴力破解。DES的基本機(jī)構(gòu)是Feistel網(wǎng)絡(luò)(Feistel結(jié)構(gòu)、Feistel密碼)。Feistel網(wǎng)絡(luò)中加密的步驟稱為輪,整個過程就是進(jìn)行若干次的輪循環(huán)。DES是一種16輪循環(huán)的Feistel網(wǎng)絡(luò)。下面看Feistel網(wǎng)絡(luò)中的輪。

我們先看其中一輪的步驟,上邊是三輪的結(jié)構(gòu)圖。
- 將輸入數(shù)據(jù)等分成左右兩部分。
- 將輸入的右側(cè)直接發(fā)送給輸出的右側(cè)。
- 將輸入的右側(cè)發(fā)送給輪函數(shù)。
- 輪函數(shù)根據(jù)右側(cè)數(shù)據(jù)和子秘鑰,計算出一串隨機(jī)序列。
- 將上一步得到的比特序列與左側(cè)數(shù)據(jù)進(jìn)行XOR(異或)運算,并將結(jié)果作為加密后的左側(cè)。
這樣第一輪下來雖然右半部沒有加密,但是第二輪就會變成左半部分參與加密。
DES的解密使用相同結(jié)構(gòu)的逆運算就行了。
三重DES
三重DES是為了加強DES的強度,將DES重復(fù)3次,得到的一種密碼算法,也叫做TDES或者3DES。
3DES并不是進(jìn)行進(jìn)行三次DES加密(加密-> 加密 ->加密),而是加密-> 解密->加密的過程。當(dāng)然每一步秘鑰不同。當(dāng)一二步秘鑰相同時,三重DES也可以當(dāng)做DES使用,因為前兩部加密、解密又變成了原文,相當(dāng)于只進(jìn)行了一次DES。
AES
AES是為了取代DES而生的一種對稱密碼算法。他并沒有使用Feistel網(wǎng)絡(luò),而是采用了Rijndael算法。Rijndael算法中一輪就經(jīng)過了逐字節(jié)替換、平移行、混合列、與輪秘鑰進(jìn)行異或。

分組密碼模式
我們知道DES和3DES一次只能加密64比特長度,AES一次可加密128或者192、256比特。但是要加密的原文遠(yuǎn)不止這么短,那怎么加密的?這時候就要對分組密碼進(jìn)行迭代,而迭代的方法就叫做分組密碼的模式。
分組密碼的模式主要有以下五種:ECB(電子密碼本模式)、CBC(密碼分組鏈接模式)、CFB(密文反饋模式)、OFB(輸出反饋模式)、CTR(計算器模式)。
ECB
ECB模式全名是電子密碼本模式,這種模式就是將分組分別加密然后拼接得到密文。因為存在弱點因此通常不被使用。
CBC
Cipher Block Chaining mode, 密碼分組鏈接模式。首先將明文分組與前一個密文分組進(jìn)行 XOR 運算,然后再進(jìn)行加密?!維SL/TLS 有用到】
CFB
Cipher FeedBack mode, 密文反饋模式。前一個密文分組會被送到密碼算法的輸入端
OFB
Output FeedBack mode, 輸出反饋模式。密碼算法的輸出會反饋到密碼算法的輸入端。
CTR
CounTeR mode, 計數(shù)器模式。通過將逐次累加的計數(shù)器進(jìn)行加密來生成密鑰流的密碼。
現(xiàn)在推薦使用CBC和CTR模式。
非對稱加密
在對稱密碼中,加密和解密的秘鑰相同,所以需要先向發(fā)送者配送秘鑰。秘鑰配送過程就可能受到攻擊者竊取或者篡改,為了解決秘鑰配送問題,非對稱密碼應(yīng)運而生。在公鑰密碼中,加密秘鑰和解密秘鑰是不同的,只要擁有了加密秘鑰,任何人都可以加密,但只有解密秘鑰才能解密。
RSA
RSA是一種公鑰密碼算法。
- 加密
在RSA中明文、密文和秘鑰都是數(shù)字。RSA的加密過程可以用下列公式表示:
密文 = 明文 E mod N
密文是代表明文的數(shù)字的E次方對N求余的結(jié)果。E和N的組合就是公鑰。
- 解密
解密公式如下:
明文 = 密文 D mod N
密文的D次方對N求余就是明文。D和N的組合是私鑰。
當(dāng)然這里的E、D、N需要滿足一定的規(guī)范的。具體計算秘鑰對就不在此贅述,想了解的可以查看數(shù)據(jù)或者上網(wǎng)了解。
RSA是利用大整數(shù)的質(zhì)因數(shù)分解的困難度來保證其健壯和攻擊困難度的。
其他非對稱加密
當(dāng)然除了RSA外,非對稱加密算法還有ELGamal、Rabin、橢圓曲線密碼。
混合密碼系統(tǒng)
混合密碼系統(tǒng)章節(jié)的主題就表明了它的用途:用對稱密碼提高速度,用公鑰密碼保護(hù)會話秘鑰。這里的會話秘鑰就是對稱密碼使用的秘鑰。
公鑰密碼當(dāng)然也不是完美的,他有兩個問題:
- 公鑰密碼的處理速度遠(yuǎn)遠(yuǎn)低于對稱密碼。
- 公鑰密碼難以抵御中間人攻擊。
混合密碼系統(tǒng)能解決上邊第一個問題,要解決第二個問題,就需要我們下一篇文章介紹的公鑰認(rèn)證技術(shù)。
混合密碼系統(tǒng)就是將對稱密碼和公鑰密碼優(yōu)勢相結(jié)合的方法。混合密碼系統(tǒng)加密過程如下圖:

- 會話秘鑰一般是通過偽隨機(jī)數(shù)生成器產(chǎn)生,是為本次通信而生成的秘鑰。
- 會話秘鑰是對稱密碼的秘鑰,同時也是公鑰密碼的明文。
認(rèn)證技術(shù)
單向散列函數(shù)
單向散列函數(shù)時為了檢驗消息的完整性而生的。它也叫做消息摘要函數(shù)、哈希函數(shù)或者雜湊函數(shù)。
單向散列函數(shù)輸出的散列值也叫做消息摘要或者指紋。
單向性
單向散列函數(shù)必須具備單向性:無法通過散列值反算出消息的性質(zhì)。
應(yīng)用
- 檢測軟件是否被篡改
- 基于口令的加密:將口令和鹽混合后計算其散列值,然后將散列值作為加密的秘鑰。
- 消息認(rèn)證碼(下面詳細(xì)介紹)
- 數(shù)字簽名
- 偽隨機(jī)數(shù)生成器
- 一次性口令
具體單向散列函數(shù)
在講解具體散列函數(shù)之前,我們先明確兩個概念:強抗碰撞性和弱抗碰撞性。
- 強抗碰撞性:要找到散列值相同的兩條不同的消息時非常困難的。
- 弱抗碰撞性:要找到和已知消息具有相同散列值的另外一條消息是非常困難的。
單向散列函數(shù)的有MD4、MD5、SHA-1、SHA-256、SHA-384、SHA-512
MD4、MD5
MD4和MD5都是產(chǎn)生128比特的散列值。
MD4已經(jīng)不安全被攻破,MD5也已失去強抗碰撞性,也就是說能產(chǎn)生具有相同散列值的兩條不同消息。
SHA-1
SHA-1的強抗碰撞性2005年也已被攻破。
SHA-2
SHA-256、SHA-384、SHA-512統(tǒng)稱為SHA-2,SHA-2目前是安全的。
所以一些重要的信息建議使用SHA-2散列函數(shù)。
消息認(rèn)證碼
單向散列函數(shù)雖然能檢測消息的完整性,但是確不能保證消息時有發(fā)送者發(fā)送的。
消息認(rèn)證碼就是為了保證消息的完整性和防偽造。它是一種確認(rèn)完整性并進(jìn)行認(rèn)證的技術(shù)。消息認(rèn)證碼簡稱:MAC。
消息認(rèn)證碼計算必須具有發(fā)送者和接受者共享秘鑰,沒有秘鑰無法計算,消息認(rèn)證碼正是利用這一特性來完成認(rèn)證的。
消息認(rèn)證碼的使用步驟如下:

消息認(rèn)證碼同樣具有秘鑰配送問題,解決方法和對稱密碼一樣可以采用公鑰密碼、Diffie-Hellman秘鑰交換、秘鑰配送中心或者其他安全方式發(fā)送秘鑰。
應(yīng)用場景
- SWIFT(環(huán)球銀行金融電信協(xié)會)銀行間交換信息用到了消息認(rèn)證碼
- IPsec,IP協(xié)議中對通信內(nèi)容的認(rèn)證和完整性教研采用的消息認(rèn)證碼
- SSL/TLS(下面章節(jié)會詳細(xì)介紹)
HMAC
HMAC是一種使用單向散列函數(shù)來構(gòu)造消息認(rèn)證碼的方法,HMAC中的H是Hash的意思。HMAC的步驟如下:

數(shù)字簽名
消息認(rèn)證碼是能解決完整性和防止偽造卻無法防止發(fā)送者否認(rèn),這個時候需要數(shù)字簽名登場了。數(shù)字簽名相當(dāng)于現(xiàn)實世界中的蓋章,使用它可以識別篡改和偽裝,還能防止否認(rèn)。
消息認(rèn)證碼之所以不能防止否認(rèn)是因為發(fā)送者和接受者使用的是同一個秘鑰,正因為是同一個秘鑰,消息認(rèn)證碼雙方都可以計算,對第三方來說無法確認(rèn)消息是誰生成的。數(shù)字簽名就不同了,它使用的是不同的秘鑰。
- 生成消息簽名:這一行為一般是消息發(fā)送方來完成的,也成為
對消息簽名。根據(jù)消息內(nèi)容計算數(shù)字簽名的值,也意味著“我認(rèn)可該消息的內(nèi)容”。 - 驗證數(shù)字簽名:一般由消息接受者來完成,也可以由驗證消息的第三方來完成。
數(shù)字簽名對簽名秘鑰和驗證秘鑰進(jìn)行了區(qū)分,使用驗證秘鑰是無法進(jìn)行簽名的。因此簽名秘鑰只能由簽名的人持有,而驗證秘鑰則是任何需要驗證的人都可以持有。是不是覺得似曾相識,沒錯這就是我們上面介紹的公鑰密碼。數(shù)字簽名正是把公鑰密碼“反過來用”實現(xiàn)的??聪旅鎸Ρ缺恚?/p>
| 私鑰 | 公鑰 | |
|---|---|---|
| 公鑰密碼 | 接受者解密時使用 | 發(fā)送者加密時使用 |
| 數(shù)字簽名 | 簽名者生成簽名時使用 | 驗證著驗證簽名時使用 |
| 誰持有秘鑰 | 個人持有 | 只要需要,任何人都可以持有 |
數(shù)字簽名中用私鑰加密相當(dāng)于生成簽名,用公鑰解密相當(dāng)于驗證簽名。數(shù)字簽名的方法有兩種:
- 直接對消息進(jìn)行簽名(耗時,因為公鑰密碼本來就非常慢)
- 對消息的散列值簽名(快)
數(shù)字簽名無法解決的問題
用數(shù)組簽名即可以識別篡改和偽裝,還能防止否認(rèn)。然而要正確使用數(shù)字簽名有一個大前提,那就是數(shù)字簽名的公鑰必須屬于真正的發(fā)送者?,F(xiàn)在我們仿佛陷入一個死循環(huán)-數(shù)字簽名是用來識別篡改、偽裝和防止否認(rèn)的,但是為此我們又必須從沒有被偽裝的發(fā)送者得到?jīng)]有被篡改的公鑰才行。為了確認(rèn)我們的得到的公鑰是合法的,我們需要使用證書。
證書
公鑰證書:里邊記有個人信息以及此人的公鑰,并有認(rèn)證機(jī)構(gòu)施加數(shù)字簽名。公鑰證書也簡稱證書。
認(rèn)證機(jī)構(gòu):能夠認(rèn)定“公鑰確實屬于此人”并能夠生成數(shù)字簽名的個人或者組織。也是對證書進(jìn)行管理的人。
下面看一個簡單的認(rèn)證示例圖:

認(rèn)證機(jī)構(gòu)
為了協(xié)助認(rèn)證機(jī)構(gòu)工作,有時還包括注冊機(jī)構(gòu)和倉庫。注冊機(jī)構(gòu)負(fù)責(zé)公鑰注冊和本人身份認(rèn)證。倉庫是保存證書的數(shù)據(jù)庫。
認(rèn)證機(jī)構(gòu)的作用:
- 生成秘鑰對
- 注冊證書
- 作廢證書與CRL
CRL是認(rèn)證機(jī)構(gòu)宣布作廢證書的一覽表。
證書的層級結(jié)構(gòu)
既然用戶的公鑰由認(rèn)證機(jī)構(gòu)添加數(shù)字簽名進(jìn)行認(rèn)證,那認(rèn)證機(jī)構(gòu)又由誰來認(rèn)證呢?對于認(rèn)證機(jī)構(gòu)可以由其他認(rèn)證機(jī)構(gòu)施加數(shù)字簽名,進(jìn)行驗證,即生成一張認(rèn)證機(jī)構(gòu)的公鑰證書。
一個認(rèn)證機(jī)構(gòu)來驗證另外一個認(rèn)證機(jī)構(gòu)的公鑰,這樣的關(guān)系可以迭代好幾層,也就形成了證書的層級機(jī)構(gòu)。
你肯定會有疑問最高級認(rèn)證機(jī)構(gòu)的公鑰(根證書)由誰來認(rèn)證呢?一般有兩種方式
- 根認(rèn)證機(jī)構(gòu)對自己公鑰進(jìn)行數(shù)字簽名也叫自簽名
- 根認(rèn)證機(jī)構(gòu)的公鑰由低級認(rèn)證機(jī)構(gòu)認(rèn)證形成環(huán)形認(rèn)證
PKI:公鑰基礎(chǔ)設(shè)施
應(yīng)用場景
下面介紹密碼技術(shù)在以下三種場景中的使用,PGP密碼軟件、SSL/TLS、區(qū)塊鏈技術(shù)。
PGP
PGP是由Philip Zimmermann個人編寫的密碼軟件,PGP是Pretty Good Privary的縮寫。
PGP的功能
-
對稱密碼
支持AES、IDES、CAST、三重DES、Blowfish、Twofish等,分組密碼模式采用CFB模式。
-
公鑰密碼
公鑰密碼支持RSA、ELGamal等,PGP不是對明文直接加密,而是使用的混合密碼系統(tǒng)來進(jìn)行加密操作。
數(shù)字簽名
-
單向散列函數(shù)
支持MD5、SHA-1、RIPEMD-160等
證書
壓縮
文本數(shù)據(jù)
大文件的拆分和拼合
鑰匙串管理
PGP混合密碼系統(tǒng)加密基本步驟和我們前面講的相同,只是多了消息的壓縮以及二進(jìn)制->文本轉(zhuǎn)換這兩個步驟,具體步驟如下圖:

SSL/TLS
我們都知道HTTP協(xié)議是不安全的,現(xiàn)在推薦使用HTTPS協(xié)議通信,HTTPS相比HTTP多了一層SSL/TLS。SSL是TLS的前身,SSL協(xié)議由于存在安全漏洞,現(xiàn)在使用的是TLS1.1、TLS1.2協(xié)議。
SSL/TLS提供了一種密碼通信的框架,這意味著它使用的對稱密碼、公鑰密碼、數(shù)字簽名、單向散列函數(shù)等技術(shù)可以像零件一樣進(jìn)行替換。
協(xié)議內(nèi)容
TLS協(xié)議是由TLS記錄協(xié)議和TLS握手協(xié)議這兩層協(xié)議疊加而成。底層TLS記錄協(xié)議負(fù)責(zé)加密,上層的TLS握手協(xié)議負(fù)責(zé)加密以外的其他各種操作。
握手協(xié)議
上層握手協(xié)議又分成4個子協(xié)議:握手協(xié)議、密碼規(guī)格變更協(xié)議、警告協(xié)議和應(yīng)用數(shù)據(jù)協(xié)議,如下圖:

- 握手協(xié)議:負(fù)責(zé)在客戶端和服務(wù)器之間協(xié)商決定密碼算法和共享秘鑰。
- 密碼規(guī)格變更協(xié)議:負(fù)責(zé)向通信對象傳達(dá)變更密碼方式的信號。
- 警告協(xié)議:負(fù)責(zé)在發(fā)生錯誤時將錯誤傳達(dá)給對方。
- 應(yīng)用數(shù)據(jù)協(xié)議:將TLS上面承載的應(yīng)用數(shù)據(jù)傳達(dá)給通信對象的協(xié)議。
TLS記錄協(xié)議
TLS協(xié)議負(fù)責(zé)消息的壓縮、加密以及數(shù)據(jù)的認(rèn)證。
小結(jié)
具體客戶端和服務(wù)器之間開始連接步驟由于篇幅原因就不在此詳細(xì)介紹,想了解的可以上網(wǎng)搜索或者閱讀原書籍。
我們來看看TLS用到了哪些密碼技術(shù)。
| 密碼技術(shù) | 作用 |
|---|---|
| 公鑰密碼 | 加密預(yù)備主密碼 |
| 單向散列函數(shù) | 構(gòu)成偽隨機(jī)數(shù)生成器 |
| 數(shù)字簽名 | 驗證服務(wù)器和客戶端的證書 |
| 偽隨機(jī)數(shù)生成器 | 生成預(yù)備主密碼、根據(jù)主密碼生成密碼、生成初始化向量 |
| 對稱密碼(CBC模式) | 確保片段的機(jī)密性 |
| 消息認(rèn)證碼 | 確保片段的完整性并進(jìn)行認(rèn)證 |
比特幣
區(qū)塊鏈就是保存比特幣全部交易記錄的公共賬簿。
關(guān)于區(qū)塊鏈相關(guān)的概念:比特幣、比特幣地址、錢包、區(qū)塊、挖礦、礦工、工作量證明等,想詳細(xì)了解推薦閱讀阮一峰的http://www.ruanyifeng.com/blog/2017/12/blockchain-tutorial.html這篇文章。我們說說它用到的密碼技術(shù)。
-
散列值
工作量證明就是通過計算符合要求的散列值來實現(xiàn)的。每個區(qū)塊中也包括當(dāng)前區(qū)塊的散列值和上一個區(qū)塊的散列值。
-
數(shù)字簽名技術(shù)
在創(chuàng)建交易時運用了數(shù)字簽名技術(shù),比特幣的數(shù)字簽名算法是橢圓曲線DSA。
-
公鑰密碼
錢包地址使用的就是公鑰密碼技術(shù)
總結(jié)
《圖解密碼技術(shù)》是一本通俗易懂的書籍,強烈推薦閱讀。本人也是第一次寫讀書筆記,有不完善的地方歡迎留言指正。