6. 消息認(rèn)證碼
"消息認(rèn)證碼 --- 消息被正確傳送了嗎?"
6.1 什么是消息認(rèn)證碼
-
Alice 和 Bob 的故事
像以前一樣,我們還是從一個(gè)Alice和Bob的故事開(kāi)始講起。不過(guò),這一次Alice和Bob分別是兩家銀行,Alice銀行通過(guò)網(wǎng)絡(luò)向Bob銀行發(fā)送了一條匯款請(qǐng)求,Bob銀行收到的請(qǐng)求內(nèi)容是:
當(dāng)然,Bob銀行所收到的匯款請(qǐng)求內(nèi)容必須與Alice銀行所發(fā)送的內(nèi)容是完全一致的。如果主動(dòng)攻擊者M(jìn)allory在中途將Alice銀行發(fā)送的匯款請(qǐng)求進(jìn)行了篡改,那么Bob銀行就必須要能夠識(shí)別出這種篡改,否則如果Mallory將收款賬戶改成了自己的賬戶,那么1000萬(wàn)元就會(huì)被盜走。
話說(shuō)回來(lái),這條匯款請(qǐng)求到底是不是Alice銀行發(fā)送的呢?有可能Alice銀行根本就沒(méi)有發(fā)送過(guò)匯款請(qǐng)求,而是由主動(dòng)攻擊者M(jìn)allory偽裝成Alice銀行發(fā)送的。如果匯款請(qǐng)求不是來(lái)自Alice銀行,那么就絕對(duì)不能執(zhí)行匯款。
現(xiàn)在我們需要關(guān)注的問(wèn)題是匯款請(qǐng)求(消息)的 “完整性" 和 “認(rèn)證" 這兩個(gè)性質(zhì)。
消息的完整性(integrity), 指的是“消息沒(méi)有被篡改"這一性質(zhì),完整性也叫一致性。如果能夠確認(rèn)匯款請(qǐng)求的內(nèi)容與Alice銀行所發(fā)出的內(nèi)容完全一致,就相當(dāng)于是確認(rèn)了消息的完整性,也就意味著消息沒(méi)有被篡改。
消息的認(rèn)證(authentication)指的是“消息來(lái)自正確的發(fā)送者"這一性質(zhì)。如果能夠確認(rèn)匯款請(qǐng)求確實(shí)來(lái)自Alice銀行,就相當(dāng)于對(duì)消息進(jìn)行了認(rèn)證,也就意味著消息不是其他人偽裝成發(fā)送者所發(fā)出的。
通過(guò)使用本章中要介紹的消息認(rèn)證碼,我們就可以同時(shí)識(shí)別出篡改和偽裝,也就是既可以確認(rèn)消息的完整性,也可以進(jìn)行認(rèn)證。
-
什么是消息認(rèn)證碼
消息認(rèn)證碼(message authentication code)是一種確認(rèn)完整性并進(jìn)行認(rèn)證的技術(shù),取三個(gè)單詞的首字母,簡(jiǎn)稱為MAC。
消息認(rèn)證碼的輸入包括任意長(zhǎng)度的消息和一個(gè)發(fā)送者與接收者之間共享的密鑰,它可以輸出固定長(zhǎng)度的數(shù)據(jù),這個(gè)數(shù)據(jù)稱為MAC值。
根據(jù)任意長(zhǎng)度的消息輸出固定長(zhǎng)度的數(shù)據(jù),這一點(diǎn)和單向散列函數(shù)很類(lèi)似。但是單向散列函數(shù)中計(jì)算散列值時(shí)不需要密鑰,而消息認(rèn)證碼中則需要使用發(fā)送者與接收者之間共享的密鑰。
要計(jì)算MAC必須持有共享密鑰,沒(méi)有共享密鑰的人就無(wú)法計(jì)算MAC值,消息認(rèn)證碼正是利用這一性質(zhì)來(lái)完成認(rèn)證的。此外,和單向散列函數(shù)的散列值一樣,哪怕消息中發(fā)生1比特的變化,MAC值也會(huì)產(chǎn)生變化,消息認(rèn)證碼正是利用這一性質(zhì)來(lái)確認(rèn)完整性的。
消息認(rèn)證碼有很多種實(shí)現(xiàn)方法,大家可以暫且這樣理解:消息認(rèn)證碼是一種與密鑰相關(guān)聯(lián)的單向散列函數(shù)。
**單向散列函數(shù)與消息認(rèn)證碼的比較**

6.2 消息認(rèn)證碼的使用步驟
我們還是以Alice銀行和Bob銀行的故事為例,來(lái)講解一下消息認(rèn)證碼的使用步驟:

- 發(fā)送者Alice與接收者Bob事先共享密鑰。
- 發(fā)送者Alice根據(jù)匯款請(qǐng)求消息計(jì)算MAC值(使用共享密鑰)。
- 發(fā)送者Alice將匯款請(qǐng)求消息和MAC值兩者發(fā)送給接收者Bob。
- 接收者Bob根據(jù)接收到的匯款請(qǐng)求消息計(jì)算MAC值(使用共享密鑰)。
- 接收者Bob將自己計(jì)算的MAC值與從Alice處收到的MAC值進(jìn)行對(duì)比。
- 如果兩個(gè)MAC值一致,則接收者Bob就可以斷定匯款請(qǐng)求的確來(lái)自Alice(認(rèn)證成功);如果不一致,則可以斷定消息不是來(lái)自Alice(認(rèn)證失?。?。
6.3 HMAC
6.3.1 HMAC介紹
HMAC是一種使用單向散列函數(shù)來(lái)構(gòu)造消息認(rèn)證碼的方法(RFC2104),其中HMAC的H就是Hash的意思。
HMAC中所使用的單向散列函數(shù)并不僅限于一種,任何高強(qiáng)度的單向散列函數(shù)都可以被用于HMAC,如果將來(lái)設(shè)計(jì)出新的單向散列函數(shù),也同樣可以使用。
使用SHA-I、MD5、RIPEMD-160所構(gòu)造的HMAC,分別稱為HMAC-SHA-1、HMAC-MD5和HMAC-RlPEMD。
**使用HMAC通過(guò)秘鑰將消息生成消息認(rèn)證碼的內(nèi)部實(shí)現(xiàn)**:

通過(guò)上述流程我們可以看出,最后得到的MAC值,一定是一個(gè)和輸入的消息以及密鑰都相關(guān)的長(zhǎng)度固定的比特序列。
6.3.2 Go中對(duì)HMAC的使用
需要使用的包
import "crypto/hmac"
使用的函數(shù)
func New(h func() hash.Hash, key []byte) hash.Hash
func Equal(mac1, mac2 []byte) bool
- hamc.New 函數(shù)
- 參數(shù)1: 創(chuàng)建一個(gè)新的使用哈希校驗(yàn)算法的hash.Hash接口, 如:
- md5.New()
- sha1.New()
- sha256.New()
- 參數(shù)2: 使用的秘鑰
- 返回值: 通過(guò)該哈希接口添加數(shù)據(jù)和計(jì)算消息認(rèn)證碼
- 添加數(shù)據(jù): Write(p []byte) (n int, err error)
- 計(jì)算結(jié)果: Sum(b []byte) []byte
- hmac.Equal 函數(shù)
- 比較兩個(gè)MAC是否相同
生成消息認(rèn)證碼:
// 生成消息認(rèn)證碼
func GenerateHMAC(src, key []byte) []byte {
// 1. 創(chuàng)建一個(gè)底層采用sha256算法的 hash.Hash 接口
myHmac := hmac.New(sha256.New, key)
// 2. 添加測(cè)試數(shù)據(jù)
myHmac.Write(src)
// 3. 計(jì)算結(jié)果
result := myHmac.Sum(nil)
return result
}
重要函數(shù)說(shuō)明
-
創(chuàng)建一個(gè)底層采用哈希算法的 hash.Hash 接口
函數(shù)對(duì)應(yīng)的包: "crypto/hmac" func New(h func() hash.Hash, key []byte) hash.Hash - 參數(shù) h: 函數(shù)指針, 返回值為hash.Hash, 可以使用哈希算法對(duì)應(yīng)的New方法, 如: -- md5.New -- sha1.New -- sha256.New -- sha256.New224 -- sha512.New -- sha512.New384 - 參數(shù) key: 和數(shù)據(jù)進(jìn)行混合運(yùn)算使用的秘鑰 - 返回值: hash.Hash 接口
驗(yàn)證消息認(rèn)證碼
func VerifyHMAC(res, src, key []byte) bool {
// 1. 創(chuàng)建一個(gè)底層采用sha256算法的 hash.Hash 接口
myHmac := hmac.New(sha256.New, key)
// 2. 添加測(cè)試數(shù)據(jù)
myHmac.Write(src)
// 3. 計(jì)算結(jié)果
result := myHmac.Sum(nil)
// 4. 比較結(jié)果
return hmac.Equal(res, result)
}
重要函數(shù)說(shuō)明:
-
比較兩個(gè)MAC是否相同
函數(shù)對(duì)應(yīng)的包: "crypto/hmac" func Equal(mac1, mac2 []byte) bool - 參數(shù) mac1, mac2: 通過(guò)哈希算法計(jì)算得到的消息認(rèn)證碼 - 返回值: 如果mac1==mac2, 返回 true; 否則, 返回 false
測(cè)試代碼
func HMacTest() {
key := []byte("我是消息認(rèn)證碼秘鑰")
src := []byte("我是消息認(rèn)證碼測(cè)試數(shù)據(jù)")
result := GenerateHMAC(src, key)
final := VerifyHMAC(result, src, key)
if final {
fmt.Println("消息認(rèn)證碼認(rèn)證成功!!!")
} else {
fmt.Println("消息認(rèn)證碼認(rèn)證失敗 ......")
}
}
6.3 消息認(rèn)證碼的密鑰配送問(wèn)題
在消息認(rèn)證碼中,需要發(fā)送者和接收者之間共享密鑰,而這個(gè)密鑰不能被主動(dòng)攻擊者M(jìn)allory獲取。如果這個(gè)密鑰落入Mallory手中,則Mallory也可以計(jì)算出MAC值,從而就能夠自由地進(jìn)行篡改和偽裝攻擊,這樣一來(lái)消息認(rèn)證碼就無(wú)法發(fā)揮作用了。
發(fā)送者和接收者需要共享密鑰,這一點(diǎn)和我們介紹的對(duì)稱加密很相似。實(shí)際上,對(duì)稱加密的密鑰配送問(wèn)題在消息認(rèn)證碼中也同樣會(huì)發(fā)生。關(guān)于秘鑰的配送后邊章節(jié)會(huì)介紹如何使用非對(duì)稱加密的方式進(jìn)行解決。
6.4 消息認(rèn)證碼無(wú)法解決的問(wèn)題
假設(shè)發(fā)送者Alice要向接收者Bob發(fā)送消息,如果使用了消息認(rèn)證碼,接收者Bob就能夠斷定自己收到的消息與發(fā)送者Alice所發(fā)出的消息是一致的,這是因?yàn)橄⒅械腗AC值只有用Alice和Bob之間共享的密鑰才能夠計(jì)算出來(lái),即便主動(dòng)攻擊者M(jìn)allory篡改消息,或者偽裝成Alice發(fā)送消息,Bob也能夠識(shí)別出消息的篡改和偽裝。
但是,消息認(rèn)證碼也不能解決所有的問(wèn)題,例如“對(duì)第三方證明"和“防止否認(rèn)",這兩個(gè)問(wèn)題就無(wú)法通過(guò)消息認(rèn)證碼來(lái)解決。下面我們來(lái)逐一解釋一下。
6.4.1 對(duì)第三方證明
假設(shè)Bob在接收了來(lái)自Alice的消息之后,想要向第三方驗(yàn)證者Victor證明這條消息的確是Alice發(fā)送的,但是用消息認(rèn)證碼無(wú)法進(jìn)行這樣的證明,這是為什么呢?
首先,Victor要校驗(yàn)MAC值,就需要知道Alice和Bob之間共享的密鑰。
假設(shè)Bob相信Victor, 同意將密鑰告訴Victor,即便如此,Victor也無(wú)法判斷這條消息是由Alice發(fā)送的,因?yàn)閂ictor可以認(rèn)為:“即使MAC值是正確的,發(fā)送這條消息的人也不一定是Alice,還有可能是Bob。"
能夠計(jì)算出正確MAC值的人只有Alice和Bob,在他們兩個(gè)人之間進(jìn)行通信時(shí),可以斷定是對(duì)方計(jì)算了MAC值,這是因?yàn)楣蚕磉@個(gè)密鑰的雙方之中,有一方就是自己。然而,對(duì)于第三方Victor、Alice或Bob卻無(wú)法證明是對(duì)方計(jì)算了MAC值,而不是自己。
使用第7章中將要介紹的數(shù)字簽名就可以實(shí)現(xiàn)對(duì)第三方的證明。
6.4.2 防止否認(rèn)
假設(shè)Bob收到了包含MAC值的消息,這個(gè)MAC值是用Alice和Bob共享的密鑰計(jì)算出來(lái)的,因此Bob能夠判斷這條消息的確來(lái)自Alice。
但是,上面我們講過(guò),Bob無(wú)法向驗(yàn)證者Victor證明這一點(diǎn),也就是說(shuō),發(fā)送者Alice可以向Victor聲稱:“我沒(méi)有向Bob發(fā)送過(guò)這條消息?!边@樣的行為就稱為否認(rèn)(repudiation)。
Alice可以說(shuō)“這條消息是Bob自己編的吧",“說(shuō)不定Bob的密鑰被主動(dòng)攻擊者M(jìn)allory給盜取了,我的密鑰可是妥善保管著呢" 等。說(shuō)白了,就是Alice和Bob吵起來(lái)了。
即便Bob拿MAC值來(lái)舉證,Victor也無(wú)法判斷Alice和Bob誰(shuí)的主張才是正確的,也就是說(shuō),用消息認(rèn)證碼無(wú)法防止否認(rèn)(nonrepudiatlon)。
6.5 總結(jié)
消息認(rèn)證碼是對(duì)消息進(jìn)行認(rèn)證并確認(rèn)其完整性的技術(shù)。通過(guò)使用發(fā)送者和接收者之間共享的密鑰,就可以識(shí)別出是否存在偽裝和篡改行為。
消息認(rèn)證碼可以使用單向散列函數(shù)HMAC, 對(duì)稱加密也可以實(shí)現(xiàn), 這里不再進(jìn)行介紹。
消息認(rèn)證碼中,由于發(fā)送者和接收者共享相同的密鑰,因此會(huì)產(chǎn)生無(wú)法對(duì)第三方證明以及無(wú)法防止否認(rèn)等問(wèn)題。在下一章中,我們將介紹能夠解決這些問(wèn)題的數(shù)字簽名。
7. 數(shù)字簽名
"數(shù)字簽名 --- 消息到底是誰(shuí)寫(xiě)的"
本章中我們將學(xué)習(xí)數(shù)字簽名的相關(guān)知識(shí)。數(shù)字簽名是一種將相當(dāng)于現(xiàn)實(shí)世界中的蓋章、簽字的功能在計(jì)算機(jī)世界中進(jìn)行實(shí)現(xiàn)的技術(shù)。使用數(shù)字簽名可以識(shí)別篡改和偽裝,還可以防止否認(rèn)。
7.1 從消息認(rèn)證到數(shù)字簽名
-
消息認(rèn)證碼的局限性
通過(guò)使用第6章中介紹的消息認(rèn)證碼,我們可以識(shí)別消息是否被篡改或者發(fā)送者身份是否被偽裝,也就是可以校驗(yàn)消息的完整性,還可以對(duì)消息進(jìn)行認(rèn)證。然而,比如在出具借條的場(chǎng)景中卻無(wú)法使用消息認(rèn)證碼,因?yàn)橄⒄J(rèn)證碼無(wú)法防止否認(rèn)。
消息認(rèn)證碼之所以無(wú)法防止否認(rèn),是因?yàn)橄⒄J(rèn)證碼需要在發(fā)送者Alice和接收者Bob兩者之間共享同一個(gè)密鑰。正是因?yàn)槊荑€是共享的,所以能夠使用消息認(rèn)證碼計(jì)算出正確MAC值的并不只有發(fā)送者Alice,接收者Bob也可以計(jì)算出正確的MAC值。由于Alice和Bob雙方都能夠計(jì)算出正確的MAC值,因此對(duì)于第三方來(lái)說(shuō),我們無(wú)法證明這條消息的確是由Alice生成的。
-
通過(guò)數(shù)字簽名解決問(wèn)題
下面請(qǐng)大家開(kāi)動(dòng)一下腦筋。假設(shè)發(fā)送者Alice和接收者Bob不需要共享一個(gè)密鑰,也就是說(shuō),Alice和Bob各自使用不同的密鑰。
我們假設(shè)Alice使用的密鑰是一個(gè)只有Alice自己才知道的私鑰。當(dāng)Alice發(fā)送消息時(shí),她用私鑰生成一個(gè)“簽名"。相對(duì)地,接收者Bob則使用一個(gè)和Alice不同的密鑰對(duì)簽名進(jìn)行驗(yàn)證。使用Bob的密鑰無(wú)法根據(jù)消息生成簽名,但是用Bob的密鑰卻可以對(duì)Alice所計(jì)算的簽名進(jìn)行驗(yàn)證,也就是說(shuō)可以知道這個(gè)簽名是否是通過(guò)Alice的密鑰計(jì)算出來(lái)的。如果真有這么一種方法的話,那么不管是識(shí)別篡改、偽裝還是防止否認(rèn)就都可以實(shí)現(xiàn)了吧 ?
實(shí)際上,這種看似很神奇的技術(shù)早就已經(jīng)問(wèn)世了,這就是數(shù)字簽名(digital signat.ure)。
7.2 簽名的生成和驗(yàn)證
讓我們來(lái)稍微整理一下。
在數(shù)字簽名技術(shù)中,出現(xiàn)了下面兩種行為:
- 生成消息簽名的行為
- 驗(yàn)證消息簽名的行為
生成消息簽名這一行為是由消息的發(fā)送者Alice來(lái)完成的,也稱為“對(duì)消息簽名”。生成簽名就是根據(jù)消息內(nèi)容計(jì)算數(shù)字簽名的值,這個(gè)行為意味著 “我認(rèn)可該消息的內(nèi)容"。
驗(yàn)證數(shù)字簽名這一行為一般是由消息的接收者Bob來(lái)完成的,但也可以由需要驗(yàn)證消息的第三方來(lái)完成,這里的第三方我們暫且將其命名為驗(yàn)證者Victor。驗(yàn)證簽名就是檢查該消息的簽名是否真的屬于Alice,驗(yàn)證的結(jié)果可以是成功或者失敗,成功就意味著這個(gè)簽名是屬于Alice的,失敗則意味著這個(gè)簽名不是屬于Alice的。
在數(shù)字簽名中,生成簽名和驗(yàn)證簽名這兩個(gè)行為需要使用各自專用的密鑰來(lái)完成。
Alice使用“簽名密鑰"來(lái)生成消息的簽名,而B(niǎo)ob和Victor則使用“驗(yàn)證密鑰"來(lái)驗(yàn)證消息的簽名。數(shù)字簽名對(duì)簽名密鑰和驗(yàn)證密鑰進(jìn)行了區(qū)分,使用驗(yàn)證密鑰是無(wú)法生成簽名的。這一點(diǎn)非常重要。此外,簽名密鑰只能由簽名的人持有,而驗(yàn)證密鑰則是任何需要驗(yàn)證簽名的人都可以持有。
剛才講的這部分內(nèi)容,是不是覺(jué)得似曾相識(shí)呢?
沒(méi)錯(cuò),這就是我們講過(guò)的非對(duì)稱加密。公鑰密碼和上面講的數(shù)字簽名的結(jié)構(gòu)非常相似。在非對(duì)稱加密中,密鑰分為加密密鑰和解密密鑰,用加密密鑰無(wú)法進(jìn)行解密。此外,解密密鑰只能由需要解密的人持有,而加密密鑰則是任何需要加密的人都可以持有。你看,數(shù)字簽名和非對(duì)稱加密是不是很像呢?
實(shí)際上,數(shù)字簽名和非對(duì)稱加密有著非常緊密的聯(lián)系,簡(jiǎn)而言之,數(shù)字簽名就是通過(guò)將非對(duì)稱加密 “反過(guò)來(lái)用” 而實(shí)現(xiàn)的。下面我們來(lái)將密鑰的使用方式總結(jié)成一張表:
| 私鑰 | 公鑰 | |
|---|---|---|
| 非對(duì)稱加密 | 接收者解密時(shí)使用 | 發(fā)送者加密時(shí)使用 |
| 數(shù)字簽名 | 簽名者生成簽名時(shí)使用 | 驗(yàn)證者驗(yàn)證簽名時(shí)使用 |
| 誰(shuí)持有秘鑰? | 個(gè)人持有 | 只要需要,任何人都可以持有 |
7.3 非對(duì)稱加密和數(shù)字簽名
下面我們?cè)賮?lái)詳細(xì)講一講非對(duì)稱加密與數(shù)字簽名之間的關(guān)系。
要實(shí)現(xiàn)數(shù)字簽名,我們可以使用第4章中介紹的非對(duì)稱加密。非對(duì)稱加密包括一個(gè)由公鑰和私鑰組成的密鑰對(duì),其中公鑰用于加密,私鑰用于解密。

數(shù)字簽名中也同樣會(huì)使用公鑰和私鑰組成的密鑰對(duì),不過(guò)這兩個(gè)密鑰的用法和非對(duì)稱加密是相反的,即用私鑰加密相當(dāng)于生成簽名,而用公鑰解密則相當(dāng)于驗(yàn)證簽名。請(qǐng)大家通過(guò)比較兩張圖示來(lái)理解一下“反過(guò)來(lái)用”到底是什么樣的情形。

那么為什么加密相當(dāng)于生成簽名,而解密相當(dāng)于驗(yàn)證簽名呢?要理解這個(gè)問(wèn)題,我們需要回想一下非對(duì)稱加密中講過(guò)的知識(shí),即組成密鑰對(duì)的兩個(gè)密鑰之間存在嚴(yán)密的數(shù)學(xué)關(guān)系,它們是一對(duì)無(wú)法拆散的伙伴。
用公鑰加密所得到的密文,只能用與該公鑰配對(duì)的私鑰才能解密:同樣地,用私鑰加密所得到的密文,也只能用與該私鑰配對(duì)的公鑰才能解密。也就是說(shuō),如果用某個(gè)公鑰成功解密了密文,那么就能夠證明這段密文是用與該公鑰配對(duì)的私鑰進(jìn)行加密所得到的。
用私鑰進(jìn)行加密這一行為只能由持有私鑰的人完成,正是基于這一事實(shí),我們才可以將用私鑰加密的密文作為簽名來(lái)對(duì)待。
由于公鑰是對(duì)外公開(kāi)的,因此任何人都能夠用公鑰進(jìn)行解密,這就產(chǎn)生了一個(gè)很大的好處,即任何人都能夠?qū)灻M(jìn)行驗(yàn)證。

7.3 數(shù)字簽名的方法
下面我們來(lái)具體介紹兩種生成和驗(yàn)證數(shù)字簽名的方法。
- 直接對(duì)消息簽名的方法
- 對(duì)消息的散列值簽名的方法
直接對(duì)消息簽名的方法比較容易理解,但實(shí)際上并不會(huì)使用;對(duì)消息的散列值簽名的方法稍微復(fù)雜一點(diǎn),但實(shí)際中我們一般都使用這種方法。
使用直接對(duì)消息簽名的方法,需要對(duì)整個(gè)消息進(jìn)行加密,非常耗時(shí),這是因?yàn)榉菍?duì)稱加密算法本來(lái)就非常慢。那么,我們能不能生成一條很短的數(shù)據(jù)來(lái)代替消息本身呢?這就是單向散列函數(shù)。
于是我們不必再對(duì)整個(gè)消息進(jìn)行加密(即對(duì)消息簽名),而是只要先用單向散列函數(shù)求出消息的散列值,然后再將散列值進(jìn)行加密(對(duì)散列值簽名)就可以了。無(wú)論消息有多長(zhǎng),散列值永遠(yuǎn)都是這么短,因此對(duì)其進(jìn)行加密(簽名)是非常輕松的。
(1)Alice用單向散列函數(shù)計(jì)算消息的散列值。
(2)Alice用自己的私鑰對(duì)散列值進(jìn)行加密。
用私鑰加密散列值所得到的密文就是Alice對(duì)這條散列值的簽名,由于只有Alice才持有自己的私鑰因此, 除了Alice以外,其他人是無(wú)法生成相同的簽名(密文)的。(3)Alice將消息和簽名發(fā)送給Bob。
(4)Bob用Alice的公鑰對(duì)收到的簽名進(jìn)行解密。
如果收到的簽名確實(shí)是用Alice的私鑰進(jìn)行加密而得到的密文(簽名),那么用Alice的公鑰應(yīng)該能夠正確 解密,解密的結(jié)果應(yīng)該等于消息的散列值。如果收到的簽名不是用Alice的私鑰進(jìn)行加密而得到的密文, 那么就無(wú)法用Alice的公鑰正確解密(解密后得到的數(shù)據(jù)看起來(lái)是隨機(jī)的)。(5)Bob將簽名解密后得到的散列值與Alice直接發(fā)送的消息的散列值進(jìn)行對(duì)比。
如果兩者一致,則簽名驗(yàn)證成功;如果兩者不一致,則簽名驗(yàn)證失敗。我們將數(shù)字簽名中生成簽名和驗(yàn)證簽名的過(guò)程整理成一張時(shí)間流程圖 。
**Alice對(duì)消息的散列值簽名, Bob驗(yàn)證簽名**

**Alice對(duì)消息的散列值簽名, Bob驗(yàn)證簽名(按時(shí)間順序)**

7.4 通過(guò)RSA實(shí)現(xiàn)數(shù)字簽名
前邊章節(jié)已經(jīng)介紹過(guò)了如何通過(guò)自己編寫(xiě)的go代碼生成非對(duì)稱加密算法RSA的公鑰和私鑰文件, 假設(shè)公鑰文件的文件名為 public.pem,私鑰文件對(duì)應(yīng)的文件名為 private.pem。
7.4.1 生成數(shù)字簽名
func SignatureRSA() ([]byte, error) {
// 1. 從秘鑰文件中讀生成的秘鑰內(nèi)容
fp, err := os.Open("private.pem")
if err != nil {
return nil, errors.New("打開(kāi)私鑰文件 - private.pem 失敗!!!")
}
// 2. 讀文件內(nèi)容
fileInfo, _ := fp.Stat()
all := make([]byte, fileInfo.Size())
_, err = fp.Read(all)
if err != nil {
return nil, errors.New("讀文件內(nèi)容失敗!!!")
}
fmt.Println("文件內(nèi)容: ", string(all))
// 3. 關(guān)閉文件
defer fp.Close()
// 4. 將數(shù)據(jù)解析成pem格式的數(shù)據(jù)塊
block, _ := pem.Decode(all)
// 5. 解析pem數(shù)據(jù)塊, 得到私鑰
priv_Key, err := x509.ParsePKCS1PrivateKey(block.Bytes)
if err != nil {
return nil, errors.New("解析私鑰失敗!!!")
}
// 待簽名數(shù)據(jù)
myData := []byte("渡遠(yuǎn)荊門(mén)外,來(lái)從楚國(guó)游。山隨平野盡,江入大荒流。月下飛天境,云生結(jié)海樓。仍憐故鄉(xiāng)水,萬(wàn)里送行舟。")
// 6. 將數(shù)據(jù)通過(guò)哈希函數(shù)生成信息摘要
myHash := sha256.New()
myHash.Write(myData)
result := myHash.Sum(nil)
// 7. 生成簽名
mySignature, err := rsa.SignPKCS1v15(rand.Reader, priv_Key, crypto.SHA256, result)
if err != nil {
return nil, errors.New("生成簽名失敗!!!")
}
return mySignature, nil
}
7.4.2 驗(yàn)證數(shù)字簽名
func VerifyRSA(src []byte) (error){
// 1. 從秘鑰文件中讀生成的秘鑰內(nèi)容
fp, err := os.Open("public.pem")
if err != nil {
return errors.New("打開(kāi)公鑰文件 - public.pem 失敗!!!")
}
// 2. 讀文件內(nèi)容
fileInfo, _ := fp.Stat()
all := make([]byte, fileInfo.Size())
num, err := fp.Read(all)
if err != nil {
return errors.New("讀文件內(nèi)容失敗!!!")
}
fmt.Println("文件大小: ", num)
// 3. 關(guān)閉文件
defer fp.Close()
// 4. 將公鑰數(shù)據(jù)解析為pem格式的數(shù)據(jù)塊
block, _ := pem.Decode(all)
// 5. 將公鑰從pem數(shù)據(jù)塊中提取出來(lái)
pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return errors.New("解析公鑰失敗!!!")
}
// 6. 公鑰接口轉(zhuǎn)換為公鑰對(duì)象
pubKey := pubInterface.(*rsa.PublicKey)
// 待認(rèn)證數(shù)據(jù)
myData := []byte("渡遠(yuǎn)荊門(mén)外,來(lái)從楚國(guó)游。山隨平野盡,江入大荒流。月下飛天境,云生結(jié)海樓。仍憐故鄉(xiāng)水,萬(wàn)里送行舟。")
// 7. 將數(shù)據(jù)通過(guò)哈希函數(shù)生成信息摘要
myHash := sha256.New()
myHash.Write(myData)
result := myHash.Sum(nil)
// 7. 數(shù)據(jù)認(rèn)證
err = rsa.VerifyPKCS1v15(pubKey, crypto.SHA256, result, src)
if err != nil {
return err
}
fmt.Println("數(shù)字簽名驗(yàn)證成功, 恭喜o(* ̄︶ ̄*)o恭喜")
return nil
}
7.5 使用橢圓曲線實(shí)現(xiàn)數(shù)字簽名
7.6 數(shù)字簽名無(wú)法解決的問(wèn)題
用數(shù)字簽名既可以識(shí)別出篡改和偽裝,還可以防止否認(rèn)。也就是說(shuō),我們同時(shí)實(shí)現(xiàn)了確認(rèn)消息的完整性、進(jìn)行認(rèn)證以及否認(rèn)防止?,F(xiàn)代社會(huì)中的計(jì)算機(jī)通信從這一技術(shù)中獲益匪淺。
然而,要正確使用數(shù)字簽名,有一個(gè)大前提,那是用于驗(yàn)證簽名的公鑰必須屬于真正的發(fā)送者。即便數(shù)字簽名算法再?gòu)?qiáng)大,如果你得到的公鑰是偽造的,那么數(shù)字簽名也會(huì)完全失效。
現(xiàn)在我們發(fā)現(xiàn)自己陷人了一個(gè)死循環(huán)一一一數(shù)字簽名是用來(lái)識(shí)別消息篡改、偽裝以及否認(rèn)的,但是為此我們又必須從沒(méi)有被偽裝的發(fā)送者得到?jīng)]有被篡改的公鑰才行。
為了能夠確認(rèn)自己得到的公鑰是否合法,我們需要使用證書(shū)。所謂證書(shū),就是將公鑰當(dāng)作一條消息,由一個(gè)可信的第三方對(duì)其簽名后所得到的公鑰。
當(dāng)然,這樣的方法只是把問(wèn)題轉(zhuǎn)移了而已。為了對(duì)證書(shū)上施加的數(shù)字簽名進(jìn)行驗(yàn)證,我們必定需要另一個(gè)公鑰,那么如何才能構(gòu)筑一個(gè)可信的數(shù)字簽名鏈條呢?又由誰(shuí)來(lái)頒發(fā)可信的證書(shū)呢?到這一步,我們就已經(jīng)踏人了社會(huì)學(xué)的領(lǐng)域。我們需要讓公鑰以及數(shù)字簽名技術(shù)成為一種社會(huì)性的基礎(chǔ)設(shè)施,即公鑰基礎(chǔ)設(shè)施(Public Key Intrastructure),簡(jiǎn)稱PKIO關(guān)于證書(shū)和PKI我們將在第8章中介紹。
8. 證書(shū)
"證書(shū) -- 為公鑰加上數(shù)字簽名"
要開(kāi)車(chē)得先考駕照.駕照上面記有本人的照片、姓名、出生日期等個(gè)人信息.以及有效期、準(zhǔn)駕車(chē)輛的類(lèi)型等信息,并由公安局在上面蓋章。我們只要看到駕照,就可以知道公安局認(rèn)定此人具有駕駛車(chē)輛的資格。
公鑰證書(shū)(Public-Key Certificate,PKC)其實(shí)和駕照很相似,里面記有姓名、組織、郵箱地址等個(gè)人信息,以及屬于此人的公鑰,并由認(rèn)證機(jī)構(gòu)(Certification Authority、Certifying Authority, CA)施加數(shù)字簽名。只要看到公鑰證書(shū),我們就可以知道認(rèn)證機(jī)構(gòu)認(rèn)定該公鑰的確屬于此人。公鑰證書(shū)也簡(jiǎn)稱為證書(shū)(certificate)。
可能很多人都沒(méi)聽(tīng)說(shuō)過(guò)認(rèn)證機(jī)構(gòu),認(rèn)證機(jī)構(gòu)就是能夠認(rèn)定 “公鑰確實(shí)屬于此人",并能夠生成數(shù)字簽名的個(gè)人或者組織。認(rèn)證機(jī)構(gòu)中有國(guó)際性組織和政府所設(shè)立的組織,也有通過(guò)提供認(rèn)證服務(wù)來(lái)盈利的一般企業(yè),此外個(gè)人也可以成立認(rèn)證機(jī)構(gòu)。
8.1 證書(shū)的應(yīng)用場(chǎng)景
下面我們來(lái)通過(guò)證書(shū)的代表性應(yīng)用場(chǎng)景來(lái)理解證書(shū)的作用。
下圖展示了Alice向Bob發(fā)送密文的場(chǎng)景,在生成密文時(shí)所使用的Bob的公鑰是通過(guò)認(rèn)證機(jī)構(gòu)獲取的。
認(rèn)證機(jī)構(gòu)必須是可信的,對(duì)于“可信的第三方”,下圖中會(huì)使用Trent這個(gè)名字,這個(gè)詞是從trust(信任)一詞演變而來(lái)的。

下面讓我們對(duì)照著上圖來(lái)看一看這些步驟具體都做了些什么。
<font color="red" size=4>Bob生成密鑰對(duì)</font>
要使用公鑰密碼進(jìn)行通信,首先需要生成密鑰對(duì)。Bob生成了一對(duì)公鑰和私鑰,并將私鑰自行妥善保管。在這里,密鑰對(duì)是由Bob自己生成的,也可以由認(rèn)證機(jī)構(gòu)代為生成。
<font color="red" size=4>Bob在認(rèn)證機(jī)構(gòu)Trent注冊(cè)自己的公鑰</font>
在這里Bob則將公鑰發(fā)送給了認(rèn)證機(jī)構(gòu)Trent,這是因?yàn)锽ob需要請(qǐng)認(rèn)證機(jī)構(gòu)Trent對(duì)他的公鑰加上數(shù)字簽名(也就是生成證書(shū))。
Trent收到Bob的公鑰后,會(huì)確認(rèn)所收到的公鑰是否為Bob本人所有(參見(jiàn)專欄:身份確認(rèn)和認(rèn)證業(yè)務(wù)準(zhǔn)則)
<font color="red" size=5>專欄:身份確認(rèn)和認(rèn)證業(yè)務(wù)準(zhǔn)則</font>
認(rèn)證機(jī)構(gòu)確認(rèn)"本人"身份的方法和認(rèn)證機(jī)構(gòu)的認(rèn)證業(yè)務(wù)準(zhǔn)則(CertificatePractice Statement, CPS,的內(nèi)容有關(guān)。如果認(rèn)證機(jī)構(gòu)提供的是測(cè)試用的服務(wù),那么可能完全不會(huì)進(jìn)行任何身份確認(rèn)。如果是政府部門(mén)運(yùn)營(yíng)的認(rèn)證機(jī)構(gòu),可能就需要根據(jù)法律規(guī)定來(lái)進(jìn)行身份確認(rèn)。如果是企業(yè)面向內(nèi)部設(shè)立的認(rèn)證機(jī)構(gòu),那就可能會(huì)給部門(mén)負(fù)責(zé)人打電話直接確認(rèn)。
例如,VeriSign的認(rèn)證業(yè)務(wù)準(zhǔn)則中將身份確認(rèn)分為Class1 ~ 3共三個(gè)等級(jí)
- Class1:通過(guò)向郵箱發(fā)送件來(lái)確認(rèn)本人身份
- Class2:通過(guò)第三方數(shù)據(jù)庫(kù)來(lái)確認(rèn)本人身份
- Class3:通過(guò)當(dāng)面認(rèn)證和身份證明來(lái)確認(rèn)本人身份
等級(jí)越高,身份確認(rèn)越嚴(yán)格。
<font color="red" size=4>認(rèn)證機(jī)構(gòu)Trent用自己的私鑰對(duì)Bob的公鑰施加數(shù)字簽名并生成證書(shū)</font>
Trent對(duì)Bob的公鑰加上數(shù)字簽名。為了生成數(shù)字簽名,需要Trent自身的私鑰,因此Trent需要事先生成好密鑰對(duì)。
<font color="red" size=4>Alice得到帶有認(rèn)證機(jī)構(gòu)Trent的數(shù)字簽名的Bob的公鑰(證書(shū))</font>
現(xiàn)在Alice需要向Bob發(fā)送密文,因此她從Trent處獲取證書(shū)。證書(shū)中包含了Bob的公鑰。
<font color="red" size=4>Alice使用認(rèn)證機(jī)構(gòu)Trent的公鑰驗(yàn)證數(shù)字簽名,確認(rèn)Bob的公鑰的合法性</font>
Alice使用認(rèn)證機(jī)構(gòu)Trent的公鑰對(duì)證書(shū)中的數(shù)字簽名進(jìn)行驗(yàn)證。如果驗(yàn)證成功,就相當(dāng)于確認(rèn)了證書(shū)中所包含的公鑰的確是屬于Bob的。到這里,Alice就得到了合法的Bob的公鑰。
<font color="red" size=4>Alice用Bob的公鑰加密消息并發(fā)送給Bob</font>
Alice用Bob的公鑰加密要發(fā)送的消息,并將消息發(fā)送給Bob。
<font color="red" size=4>Bob用自己的私鑰解密密文得到Alice的消息</font>
Bob收到Alice發(fā)送的密文,然后用自己的私鑰解密,這樣就能夠看到Alice的消息了。
<font color="blue" size=4>上面就是利用認(rèn)證機(jī)構(gòu)Trent進(jìn)行公鑰密碼通信的流程。其中1、2、3這幾個(gè)步驟僅在注冊(cè)新公鑰時(shí)才會(huì)進(jìn)行,并不是每次通信都需要。此外,步驟 4 僅在Alice第一次用公鑰密碼向Bob發(fā)送消息時(shí)才需要進(jìn)行,只要Alice將Bob的公鑰保存在電腦中,在以后的通信中就可以直接使用了。</font>
8.2 證書(shū)標(biāo)準(zhǔn)規(guī)范X.509
證書(shū)是由認(rèn)證機(jī)構(gòu)頒發(fā)的,使用者需要對(duì)證書(shū)進(jìn)行驗(yàn)證,因此如果證書(shū)的格式千奇百怪那就不方便了。于是,人們制定了證書(shū)的標(biāo)準(zhǔn)規(guī)范,其中使用最廣泛的是由ITU(International TelecommumcationUnion,國(guó)際電信聯(lián)盟)和ISO(IntemationalOrganizationforStandardization, 國(guó)際標(biāo)準(zhǔn)化組織)制定的X.509規(guī)范。很多應(yīng)用程序都支持x.509并將其作為證書(shū)生成和交換的標(biāo)準(zhǔn)規(guī)范。
X.509是一種非常通用的證書(shū)格式。所有的證書(shū)都符合ITU-T X.509國(guó)際標(biāo)準(zhǔn),因此(理論上)為一種應(yīng)用創(chuàng)建的證書(shū)可以用于任何其他符合X.509標(biāo)準(zhǔn)的應(yīng)用。X.509證書(shū)的結(jié)構(gòu)是用ASN1(Abstract Syntax Notation One)進(jìn)行描述數(shù)據(jù)結(jié)構(gòu),并使用ASN.1語(yǔ)法進(jìn)行編碼。
在一份證書(shū)中,必須證明公鑰及其所有者的姓名是一致的。對(duì)X.509證書(shū)來(lái)說(shuō),認(rèn)證者總是CA或由CA指定的人,一份X.509證書(shū)是一些標(biāo)準(zhǔn)字段的集合,這些字段包含有關(guān)用戶或設(shè)備及其相應(yīng)公鑰的信息。X.509標(biāo)準(zhǔn)定義了證書(shū)中應(yīng)該包含哪些信息,并描述了這些信息是如何編碼的(即數(shù)據(jù)格式)
一般來(lái)說(shuō),一個(gè)數(shù)字證書(shū)內(nèi)容可能包括基本數(shù)據(jù)(版本、序列號(hào)) 、所簽名對(duì)象信息( 簽名算法類(lèi)型、簽發(fā)者信息、有效期、被簽發(fā)人、簽發(fā)的公開(kāi)密鑰)、CA的數(shù)字簽名,等等。
8.2.1 證書(shū)規(guī)范
前使用最廣泛的標(biāo)準(zhǔn)為ITU和ISO聯(lián)合制定的X.509的 v3版本規(guī)范 (RFC5280), 其中定義了如下證書(shū)信息域:
- <font color="red">版本號(hào)(Version Number)</font>:規(guī)范的版本號(hào),目前為版本3,值為0x2;
- <font color="red">序列號(hào)(Serial Number)</font>:由CA維護(hù)的為它所發(fā)的每個(gè)證書(shū)分配的一的列號(hào),用來(lái)追蹤和撤銷(xiāo)證書(shū)。只要擁有簽發(fā)者信息和序列號(hào),就可以唯一標(biāo)識(shí)一個(gè)證書(shū),最大不能過(guò)20個(gè)字節(jié);
<font color="red">簽名算法(Signature Algorithm)</font>:數(shù)字簽名所采用的算法,如:
- sha256-with-RSA-Encryption
- ccdsa-with-SHA2S6;
- <font color="red">頒發(fā)者(Issuer)</font>:發(fā)證書(shū)單位的標(biāo)識(shí)信息,如 ” C=CN,ST=Beijing, L=Beijing, O=org.example.com,CN=ca.org。example.com ”;
- <font color="red">有效期(Validity)</font>: 證書(shū)的有效期很,包括起止時(shí)間。
- <font color="red">主體(Subject)</font> : 證書(shū)擁有者的標(biāo)識(shí)信息(Distinguished Name),如:" C=CN,ST=Beijing, L=Beijing, CN=person.org.example.com”;
- <font color="red">主體的公鑰信息(SubJect Public Key Info)</font>:所保護(hù)的公鑰相關(guān)的信息:
- 公鑰算法 (Public Key Algorithm)公鑰采用的算法;
- 主體公鑰(Subject Unique Identifier):公鑰的內(nèi)容。
- <font color="red">頒發(fā)者唯一號(hào)(Issuer Unique Identifier)</font>:代表頒發(fā)者的唯一信息,僅2、3版本支持,可選;
- <font color="red">主體唯一號(hào)(Subject Unique Identifier)</font>:代表?yè)碛凶C書(shū)實(shí)體的唯一信息,僅2,3版本支持,可選:
- <font color="red">擴(kuò)展(Extensions,可選)</font>: 可選的一些擴(kuò)展。中可能包括:
- Subject Key Identifier:實(shí)體的秘鑰標(biāo)識(shí)符,區(qū)分實(shí)體的多對(duì)秘鑰;
- Basic Constraints:一指明是否屬于CA;
- Authority Key Identifier:證書(shū)頒發(fā)者的公鑰標(biāo)識(shí)符;
- CRL Distribution Points: 撤銷(xiāo)文件的頒發(fā)地址;
- Key Usage:證書(shū)的用途或功能信息。
此外,證書(shū)的頒發(fā)者還需要對(duì)證書(shū)內(nèi)容利用自己的私鑰添加簽名, 以防止別人對(duì)證書(shū)的內(nèi)容進(jìn)行篡改。
8.2.2 證書(shū)格式
X.509規(guī)范中一般推薦使用PEM(Privacy Enhanced Mail)格式來(lái)存儲(chǔ)證書(shū)相關(guān)的文件。證書(shū)文件的文件名后綴一般為 .crt 或 .cer 。對(duì)應(yīng)私鑰文件的文件名后綴一般為 .key。證書(shū)請(qǐng)求文件的文件名后綴為 .csr 。有時(shí)候也統(tǒng)一用pem作為文件名后綴。
PEM格式采用文本方式進(jìn)行存儲(chǔ)。一般包括首尾標(biāo)記和內(nèi)容塊,內(nèi)容塊采用Base64進(jìn)行編碼。
編碼格式總結(jié):
- X.509 DER(Distinguished Encoding Rules)編碼,后綴為:.der .cer .crt
- X.509 BASE64編碼(PEM格式),后綴為:.pem .cer .crt
例如,一個(gè)PEM格式(base64編碼)的示例證書(shū)文件內(nèi)容如下所示:
-----BEGIN CERTIFICATE-----
MIIDyjCCArKgAwIBAgIQdZfkKrISoINLporOrZLXPTANBgkqhkiG9w0BAQsFADBn
MSswKQYDVQQLDCJDcmVhdGVkIGJ5IGh0dHA6Ly93d3cuZmlkZGxlcjIuY29tMRUw
EwYDVQQKDAxET19OT1RfVFJVU1QxITAfBgNVBAMMGERPX05PVF9UUlVTVF9GaWRk
bGVyUm9vdDAeFw0xNzA0MTExNjQ4MzhaFw0yMzA0MTExNjQ4MzhaMFoxKzApBgNV
BAsMIkNyZWF0ZWQgYnkgaHR0cDovL3d3dy5maWRkbGVyMi5jb20xFTATBgNVBAoM
DERPX05PVF9UUlVTVDEUMBIGA1UEAwwLKi5iYWlkdS5jb20wggEiMA0GCSqGSIb3
DQEBAQUAA4IBDwAwggEKAoIBAQDX0AM198jxwRoKgwWsd9oj5vI0and9v9SB9Chl
gZEu6G9ZA0C7BucsBzJ2bl0Mf6qq0Iee1DfeydfEKyTmBKTafgb2DoQE3OHZjy0B
QTJrsOdf5s636W5gJp4f7CUYYA/3e1nxr/+AuG44Idlsi17TWodVKjsQhjzH+bK6
8ukQZyel1SgBeQOivzxXe0rhXzrocoeKZFmUxLkUpm+/mX1syDTdaCmQ6LT4KYYi
soKe4f+r2tLbUzPKxtk2F1v3ZLOjiRdzCOA27e5n88zdAFrCmMB4teG/azCSAH3g
Yb6vaAGaOnKyDLGunW51sSesWBpHceJnMfrhwxCjiv707JZtAgMBAAGjfzB9MA4G
A1UdDwEB/wQEAwIEsDATBgNVHSUEDDAKBggrBgEFBQcDATAWBgNVHREEDzANggsq
LmJhaWR1LmNvbTAfBgNVHSMEGDAWgBQ9UIffUQSuwWGOm+o74JffZJNadjAdBgNV
HQ4EFgQUQh8IksZqcMVmKrIibTHLbAgLRGgwDQYJKoZIhvcNAQELBQADggEBAC5Y
JndwXpm0W+9SUlQhAUSE9LZh+DzcSmlCWtBk+SKBwmAegbfNSf6CgCh0VY6iIhbn
GlszqgAOAqVMxAEDlR/YJTOlAUXFw8KICsWdvE01xtHqhk1tCK154Otci60Wu+tz
1t8999GPbJskecbRDGRDSA/gQGZJuL0rnmIuz3macSVn6tH7NwdoNeN68Uj3Qyt5
orYv1IFm8t55224ga8ac1y90hK4R5HcvN71aIjMKrikgynK0E+g45QypHRIe/z0S
/1W/6rqTgfN6OWc0c15hPeJbTtkntB5Fqd0sfsnKkW6jPsKQ+z/+vZ5XqzdlFupQ
29F14ei8ZHl9aLIHP5s=
-----END CERTIFICATE-----
證書(shū)中的解析出來(lái)的內(nèi)容:
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
10:e6:fc:62:b7:41:8a:d5:00:5e:45:b6
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=BE, O=GlobalSign nv-sa, CN=GlobalSign Organization Validation CA-SHA256-G2
Validity
Not Before: Nov 21 08:00:00 2016 GMT
Not After : Nov 22 07:59:59 2017 GMT
Subject: C=US, ST=California, L=San Francisco, O=Wikimedia Foundation, Inc., CN=*.wikipedia.org
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (256 bit)
pub:
04:c9:22:69:31:8a:d6:6c:ea:da:c3:7f:2c:ac:a5:
af:c0:02:ea:81:cb:65:b9:fd:0c:6d:46:5b:c9:1e:
ed:b2:ac:2a:1b:4a:ec:80:7b:e7:1a:51:e0:df:f7:
c7:4a:20:7b:91:4b:20:07:21:ce:cf:68:65:8c:c6:
9d:3b:ef:d5:c1
ASN1 OID: prime256v1
NIST CURVE: P-256
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature, Key Agreement
Authority Information Access:
CA Issuers - URI:http://secure.globalsign.com/cacert/gsorganizationvalsha2g2r1.crt
OCSP - URI:http://ocsp2.globalsign.com/gsorganizationvalsha2g2
X509v3 Certificate Policies:
Policy: 1.3.6.1.4.1.4146.1.20
CPS: https://www.globalsign.com/repository/
Policy: 2.23.140.1.2.2
X509v3 Basic Constraints:
CA:FALSE
X509v3 CRL Distribution Points:
Full Name:
URI:http://crl.globalsign.com/gs/gsorganizationvalsha2g2.crl
X509v3 Subject Alternative Name:
DNS:*.wikipedia.org, DNS:*.m.mediawiki.org, DNS:*.m.wikibooks.org, DNS:*.m.wikidata.org, DNS:*.m.wikimedia.org, DNS:*.m.wikimediafoundation.org, DNS:*.m.wikinews.org, DNS:*.m.wikipedia.org, DNS:*.m.wikiquote.org, DNS:*.m.wikisource.org, DNS:*.m.wikiversity.org, DNS:*.m.wikivoyage.org, DNS:*.m.wiktionary.org, DNS:*.mediawiki.org, DNS:*.planet.wikimedia.org, DNS:*.wikibooks.org, DNS:*.wikidata.org, DNS:*.wikimedia.org, DNS:*.wikimediafoundation.org, DNS:*.wikinews.org, DNS:*.wikiquote.org, DNS:*.wikisource.org, DNS:*.wikiversity.org, DNS:*.wikivoyage.org, DNS:*.wiktionary.org, DNS:*.wmfusercontent.org, DNS:*.zero.wikipedia.org, DNS:mediawiki.org, DNS:w.wiki, DNS:wikibooks.org, DNS:wikidata.org, DNS:wikimedia.org, DNS:wikimediafoundation.org, DNS:wikinews.org, DNS:wikiquote.org, DNS:wikisource.org, DNS:wikiversity.org, DNS:wikivoyage.org, DNS:wiktionary.org, DNS:wmfusercontent.org, DNS:wikipedia.org
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication
X509v3 Subject Key Identifier:
28:2A:26:2A:57:8B:3B:CE:B4:D6:AB:54:EF:D7:38:21:2C:49:5C:36
X509v3 Authority Key Identifier:
keyid:96:DE:61:F1:BD:1C:16:29:53:1C:C0:CC:7D:3B:83:00:40:E6:1A:7C
Signature Algorithm: sha256WithRSAEncryption
8b:c3:ed:d1:9d:39:6f:af:40:72:bd:1e:18:5e:30:54:23:35:
...
8.2.3 CA證書(shū)
證書(shū)是用來(lái)證明某某東西確實(shí)是某某東西的東西(是不是像繞口令?)。通俗地說(shuō),證書(shū)就好比上文里面的公章。通過(guò)公章,可以證明對(duì)應(yīng)的證件的真實(shí)性。
理論上,人人都可以找個(gè)證書(shū)工具,自己做一個(gè)證書(shū)。那如何防止壞人自己制作證書(shū)出來(lái)騙人捏?請(qǐng)看后續(xù) CA 的介紹。
CA是Certificate Authority的縮寫(xiě),也叫“證書(shū)授權(quán)中心”。
它是負(fù)責(zé)管理和簽發(fā)證書(shū)的第三方機(jī)構(gòu), 好比一個(gè)可信任的中介公司。一般來(lái)說(shuō),CA必須是所有行業(yè)和所有公眾都信任的、認(rèn)可的。因此它必須具有足夠的權(quán)威性。就好比A、B兩公司都必須信任C公司,才會(huì)找 C 公司作為公章的中介。
-
CA證書(shū)
CA 證書(shū),顧名思義,就是CA頒發(fā)的證書(shū)。
前面已經(jīng)說(shuō)了,人人都可以找工具制作證書(shū)。但是你一個(gè)小破孩制作出來(lái)的證書(shū)是沒(méi)啥用處的。因?yàn)槟悴皇菣?quán)威的CA機(jī)關(guān),你自己搞的證書(shū)不具有權(quán)威性。
比如,某個(gè)壞人自己刻了一個(gè)公章,蓋到介紹信上。但是別人一看,不是受信任的中介公司的公章,就不予理睬。壞蛋的陰謀就不能得逞啦。
-
證書(shū)信任鏈
證書(shū)直接是可以有信任關(guān)系的, 通過(guò)一個(gè)證書(shū)可以證明另一個(gè)證書(shū)也是真實(shí)可信的. 實(shí)際上,證書(shū)之間的信任關(guān)系,是可以嵌套的。比如,C 信任 A1,A1 信任 A2,A2 信任 A3......這個(gè)叫做證書(shū)的信任鏈。只要你信任鏈上的頭一個(gè)證書(shū),那后續(xù)的證書(shū),都是可以信任滴。
假設(shè) C 證書(shū)信任 A 和 B;然后 A 信任 A1 和 A2;B 信任 B1 和 B2。則它們之間,構(gòu)成如下的一個(gè)樹(shù)形關(guān)系(一個(gè)倒立的樹(shù))。

處于最頂上的樹(shù)根位置的那個(gè)證書(shū),就是“根證書(shū)”。除了根證書(shū),其它證書(shū)都要依靠上一級(jí)的證書(shū),來(lái)證明自己。那誰(shuí)來(lái)證明“根證書(shū)”可靠捏?實(shí)際上,根證書(shū)自己證明自己是可靠滴(或者換句話說(shuō),根證書(shū)是不需要被證明滴)。
聰明的同學(xué)此刻應(yīng)該意識(shí)到了:根證書(shū)是整個(gè)證書(shū)體系安全的根本。所以,如果某個(gè)證書(shū)體系中,根證書(shū)出了問(wèn)題(不再可信了),那么所有被根證書(shū)所信任的其它證書(shū),也就不再可信了。
-
證書(shū)有啥用
-
驗(yàn)證網(wǎng)站是否可信(針對(duì)HTTPS)
通常,我們?nèi)绻L問(wèn)某些敏感的網(wǎng)頁(yè)(比如用戶登錄的頁(yè)面),其協(xié)議都會(huì)使用 HTTPS 而不是 HTTP。因?yàn)?HTTP 協(xié)議是明文的,一旦有壞人在偷窺你的網(wǎng)絡(luò)通訊,他/她就可以看到網(wǎng)絡(luò)通訊的內(nèi)容(比如你的密碼、銀行帳號(hào)、等);而 HTTPS 是加密的協(xié)議,可以保證你的傳輸過(guò)程中,壞蛋無(wú)法偷窺。
但是,千萬(wàn)不要以為,HTTPS 協(xié)議有了加密,就可高枕無(wú)憂了。俺再舉一個(gè)例子來(lái)說(shuō)明,光有加密是不夠滴。假設(shè)有一個(gè)壞人,搞了一個(gè)假的網(wǎng)銀的站點(diǎn),然后誘騙你上這個(gè)站點(diǎn)。假設(shè)你又比較單純,一不留神,就把你的帳號(hào),口令都輸入進(jìn)去了。那這個(gè)壞蛋的陰謀就得逞鳥(niǎo)。
為了防止壞人這么干,HTTPS 協(xié)議除了有加密的機(jī)制,還有一套證書(shū)的機(jī)制。通過(guò)證書(shū)來(lái)確保,某個(gè)站點(diǎn)確實(shí)就是某個(gè)站點(diǎn)。
有了證書(shū)之后,當(dāng)你的瀏覽器在訪問(wèn)某個(gè) HTTPS 網(wǎng)站時(shí),會(huì)驗(yàn)證該站點(diǎn)上的 CA 證書(shū)(類(lèi)似于驗(yàn)證介紹信的公章)。如果瀏覽器發(fā)現(xiàn)該證書(shū)沒(méi)有問(wèn)題(證書(shū)被某個(gè)根證書(shū)信任、證書(shū)上綁定的域名和該網(wǎng)站的域名一致、證書(shū)沒(méi)有過(guò)期),那么頁(yè)面就直接打開(kāi);否則的話,瀏覽器會(huì)給出一個(gè)警告,告訴你該網(wǎng)站的證書(shū)存在某某問(wèn)題,是否繼續(xù)訪問(wèn)該站點(diǎn)?下面給出 IE 和 Firefox 的抓圖:
03113237-5408b6ece0c84744b106e639ddf4956b.png
03113237-1369f659d6e4496e8bb3a742198cef63.png大多數(shù)知名的網(wǎng)站,如果用了 HTTPS 協(xié)議,其證書(shū)都是可信的(也就不會(huì)出現(xiàn)上述警告)。所以,今后你如果上某個(gè)知名網(wǎng)站,發(fā)現(xiàn)瀏覽器跳出上述警告,你就要小心啦!
-
驗(yàn)證某文件是否可信(是否被篡改)
證書(shū)除了可以用來(lái)驗(yàn)證某個(gè)網(wǎng)站,還可以用來(lái)驗(yàn)證某個(gè)文件是否被篡改。具體是通過(guò)證書(shū)來(lái)制作文件的數(shù)字簽名。制作數(shù)字簽名的過(guò)程太專業(yè),咱就不說(shuō)了。后面專門(mén)告訴大家如何驗(yàn)證文件的數(shù)字簽名??紤]到大多數(shù)人用 Windows 系統(tǒng),俺就拿 Windows 的例子來(lái)說(shuō)事兒。
比如,俺手頭有一個(gè) Google Chrome的安裝文件(帶有數(shù)字簽名)。當(dāng)俺查看該文件的屬性,會(huì)看到如下的界面。眼神好的同學(xué),會(huì)注意到到上面有個(gè)“數(shù)字簽名”的標(biāo)簽頁(yè)。如果沒(méi)有出現(xiàn)這個(gè)標(biāo)簽頁(yè),就說(shuō)明該文件沒(méi)有附帶數(shù)字簽名。
1533294208392.png一般來(lái)說(shuō),簽名列表中,有且僅有一個(gè)簽名。選中它,點(diǎn)“詳細(xì)信息”按鈕。跳出如下界面:
通常這個(gè)界面會(huì)顯示一行字:“該數(shù)字簽名正常”(圖中紅圈標(biāo)出)。如果有這行字,就說(shuō)明該文件從出廠到你手里,中途沒(méi)有被篡改過(guò)(是原裝滴、是純潔滴)。如果該文件被篡改過(guò)了(比如,感染了病毒、被注入木馬),那么對(duì)話框會(huì)出現(xiàn)一個(gè)警告提示“該數(shù)字簽名無(wú)效”
1533294414623.png不論簽名是否正常,你都可以點(diǎn)“查看證書(shū)”按鈕。這時(shí)候,會(huì)跳出證書(shū)的對(duì)話框。如下:
1533294685323.png1533294711691.png從后一個(gè)界面,可以看到剛才說(shuō)的證書(shū)信任鏈。圖中的信任鏈有3層:
- 第1層是根證書(shū)(verisign)。
- 第2層是 symantec 專門(mén)用來(lái)簽名的證書(shū)。
- 第3層是 Google自己的證書(shū)。
目前大多數(shù)知名的公司(或組織機(jī)構(gòu)),其發(fā)布的可執(zhí)行文件(比如軟件安裝包、驅(qū)動(dòng)程序、安全補(bǔ)?。?,都帶有數(shù)字簽名。你可以自己去看一下。
建議大伙兒在安裝軟件之前,都先看看是否有數(shù)字簽名?如果有,就按照上述步驟驗(yàn)證一把。一旦數(shù)字簽名是壞的,那可千萬(wàn)別裝。
-
8.3 公鑰基礎(chǔ)設(shè)施(PKI)
僅制定證書(shū)的規(guī)范還不足以支持公鑰的實(shí)際運(yùn)用,我們還需要很多其他的規(guī)范,例如證書(shū)應(yīng)該由誰(shuí)來(lái)頒發(fā),如何頒發(fā),私鑰泄露時(shí)應(yīng)該如何作廢證書(shū),計(jì)算機(jī)之間的數(shù)據(jù)交換應(yīng)采用怎樣的格式等。這一節(jié)我們將介紹能夠使公鑰的運(yùn)用更加有效的公鑰基礎(chǔ)設(shè)施。
8.3.1 什么是公鑰基礎(chǔ)設(shè)施
公鑰基礎(chǔ)設(shè)施(Public-Key infrastructure)是為了能夠更有效地運(yùn)用公鑰而制定的一系列規(guī)范和規(guī)格的總稱。公鑰基礎(chǔ)設(shè)施一般根據(jù)其英語(yǔ)縮寫(xiě)而簡(jiǎn)稱為PKI。
PKI只是一個(gè)總稱,而并非指某一個(gè)單獨(dú)的規(guī)范或規(guī)格。例如,RSA公司所制定的PKCS(Public-Key Cryptography Standards,公鑰密碼標(biāo)準(zhǔn))系列規(guī)范也是PKI的一種,而互聯(lián)網(wǎng)規(guī)格RFC(Requestfor Comments)中也有很多與PKI相關(guān)的文檔。此外,X.509這樣的規(guī)范也是PKI的一種。在開(kāi)發(fā)PKI程序時(shí)所使用的由各個(gè)公司編寫(xiě)的API(Application Programming Interface, 應(yīng)用程序編程接口)和規(guī)格設(shè)計(jì)書(shū)也可以算是PKI的相關(guān)規(guī)格。
因此,根據(jù)具體所采用的規(guī)格,PKI也會(huì)有很多變種,這也是很多人難以整體理解PKI的原因之一。
為了幫助大家整體理解PKI,我們來(lái)簡(jiǎn)單總結(jié)一下PKI的基本組成要素(用戶、認(rèn)證機(jī)構(gòu)、倉(cāng)庫(kù))以及認(rèn)證機(jī)構(gòu)所負(fù)責(zé)的工作。
8.3.2 PKI的組成要素
PKI的組成要素主要有以下三個(gè):
- 用戶 --- 使用PKI的人
- 認(rèn)證機(jī)構(gòu) --- 頒發(fā)證書(shū)的人
- 倉(cāng)庫(kù) --- 保存證書(shū)的數(shù)據(jù)庫(kù)

用戶
用戶就是像Alice、Bob這樣使用PKI的人。用戶包括兩種:一種是希望使用PKI注冊(cè)自己的公鑰的人,另一種是希望使用已注冊(cè)的公鑰的人。我們來(lái)具體看一下這兩種用戶所要進(jìn)行的操作。
-
注冊(cè)公鑰的用戶所進(jìn)行的操作
- 生成密鑰對(duì)(也可以由認(rèn)證機(jī)構(gòu)生成)
- 在認(rèn)證機(jī)構(gòu)注冊(cè)公鑰
- 向認(rèn)證機(jī)構(gòu)申請(qǐng)證書(shū)
- 根據(jù)需要申請(qǐng)作廢已注冊(cè)的公鑰
- 解密接收到的密文
- 對(duì)消息進(jìn)行數(shù)字簽名
-
使用已注冊(cè)公鑰的用戶所進(jìn)行的操作
- 將消息加密后發(fā)送給接收者
- 驗(yàn)證數(shù)字簽名
/* ==================== 小知識(shí)點(diǎn) ==================== 瀏覽器如何驗(yàn)證SSL證書(shū) 1. 在IE瀏覽器的菜單中點(diǎn)擊“工具 /Internet選項(xiàng)”,選擇“內(nèi)容”標(biāo)簽,點(diǎn)擊“證書(shū)”按鈕,然后就可以看到IE 瀏覽器已經(jīng)信任了許多“中級(jí)證書(shū)頒發(fā)機(jī)構(gòu)”和“受信任的根證書(shū)頒發(fā)機(jī) 構(gòu)。當(dāng)我們?cè)谠L問(wèn)該網(wǎng)站時(shí),瀏覽器 就會(huì)自動(dòng)下載該網(wǎng)站的SSL證書(shū),并對(duì)證書(shū)的安全性進(jìn)行檢查。 2. 由于證書(shū)是分等級(jí)的,網(wǎng)站擁有者可能從根證書(shū)頒發(fā)機(jī)構(gòu)領(lǐng)到證書(shū),也可能從根證書(shū)的下一級(jí)(如某個(gè)國(guó)家 的認(rèn)證中心,或者是某個(gè)省發(fā)出的證書(shū))領(lǐng)到證書(shū)。假設(shè)我們正在訪問(wèn)某個(gè)使用 了 SSL技術(shù)的網(wǎng)站,IE瀏 覽器就會(huì)收到了一個(gè)SSL證書(shū),如果這個(gè)證書(shū)是由根證書(shū)頒發(fā)機(jī)構(gòu)簽發(fā)的,IE瀏覽器就會(huì)按照下面的步驟來(lái) 檢查:瀏覽器使用內(nèi) 置的根證書(shū)中的公鑰來(lái)對(duì)收到的證書(shū)進(jìn)行認(rèn)證,如果一致,就表示該安全證書(shū)是由可信 任的頒證機(jī)構(gòu)簽發(fā)的,這個(gè)網(wǎng)站就是安全可靠的;如果該SSL證書(shū)不是根服 務(wù)器簽發(fā)的,瀏覽器就會(huì)自動(dòng)檢 查上一級(jí)的發(fā)證機(jī)構(gòu),直到找到相應(yīng)的根證書(shū)頒發(fā)機(jī)構(gòu),如果該根證書(shū)頒發(fā)機(jī)構(gòu)是可信的,這個(gè)網(wǎng)站的SSL證 書(shū)也是可信的。 */
認(rèn)證機(jī)構(gòu)(CA)
認(rèn)證機(jī)構(gòu)(Certification Authority,CA)是對(duì)證書(shū)進(jìn)行管理的人。上面的圖中我們給它起了一個(gè)名字叫作Trent。認(rèn)證機(jī)構(gòu)具體所進(jìn)行的操作如下:
-
生成密鑰對(duì) (也可以由用戶生成)
生成密鑰對(duì)有兩種方式:一種是由PKI用戶自行生成,一種是由認(rèn)證機(jī)構(gòu)來(lái)生成。在認(rèn)證機(jī)構(gòu)生成用戶密鑰對(duì)的情況下,認(rèn)證機(jī)構(gòu)需要將私鑰發(fā)送給用戶,這時(shí)就需要使用PKCS#12(Personal Information Exchange Syntax Standard)等規(guī)范。
-
在注冊(cè)公鑰時(shí)對(duì)本人身份進(jìn)行認(rèn)證, 生成并頒發(fā)證書(shū)
在用戶自行生成密鑰對(duì)的情況下,用戶會(huì)請(qǐng)求認(rèn)證機(jī)構(gòu)來(lái)生成證書(shū)。申請(qǐng)證書(shū)時(shí)所使用的規(guī)范是由PKCS#10(Certification Request Syntax Standard)定義的。
認(rèn)證機(jī)構(gòu)根據(jù)其認(rèn)證業(yè)務(wù)準(zhǔn)則(Certification Practice Statement,CPS)對(duì)用戶的身份進(jìn)行認(rèn)證,并生成證書(shū)。在生成證書(shū)時(shí),需要使用認(rèn)證機(jī)構(gòu)的私鑰來(lái)進(jìn)行數(shù)字簽名。生成的證書(shū)格式是由PKCS#6 (Extended-Certificate Syntax Standard)和 X.509定義的。
-
作廢證書(shū)
當(dāng)用戶的私鑰丟失、被盜時(shí),認(rèn)證機(jī)構(gòu)需要對(duì)證書(shū)進(jìn)行作廢(revoke)。此外,即便私鑰安然無(wú)恙,有時(shí)候也需要作廢證書(shū),例如用戶從公司離職導(dǎo)致其失去私鑰的使用權(quán)限,或者是名稱變更導(dǎo)致和證書(shū)中記載的內(nèi)容不一致等情況。
紙質(zhì)證書(shū)只要撕毀就可以作廢了,但這里的證書(shū)是數(shù)字信息,即便從倉(cāng)庫(kù)中刪除也無(wú)法作廢,因?yàn)橛脩魰?huì)保存證書(shū)的副本,但認(rèn)證機(jī)構(gòu)又不能人侵用戶的電腦將副本刪除。
要作廢證書(shū),認(rèn)證機(jī)構(gòu)需要制作一張證書(shū)==作廢清單(Certificate Revocation List),簡(jiǎn)稱為CRL==。
CRL是認(rèn)證機(jī)構(gòu)宣布作廢的證書(shū)一覽表,具體來(lái)說(shuō),是一張已作廢的證書(shū)序列號(hào)的清單,并由認(rèn)證機(jī)構(gòu)加上數(shù)字簽名。證書(shū)序列號(hào)是認(rèn)證機(jī)構(gòu)在頒發(fā)證書(shū)時(shí)所賦予的編號(hào),在證書(shū)中都會(huì)記載。
PKI用戶需要從認(rèn)證機(jī)構(gòu)獲取最新的CRL,并查詢自己要用于驗(yàn)證簽名(或者是用于加密)的公鑰證書(shū)是否已經(jīng)作廢這個(gè)步驟是非常重要的。
假設(shè)我們手上有Bob的證書(shū),該證書(shū)有合法的認(rèn)證機(jī)構(gòu)簽名,而且也在有效期內(nèi),但僅憑這些還不能說(shuō)明該證書(shū)一定是有效的,還需要查詢認(rèn)證機(jī)構(gòu)最新的CRL,并確認(rèn)該證書(shū)是否有效。一般來(lái)說(shuō),這個(gè)檢查不是由用戶自身來(lái)完成的,而是應(yīng)該由處理該證書(shū)的軟件來(lái)完成,但有很多軟件并沒(méi)有及時(shí)更能CRL。
認(rèn)證機(jī)構(gòu)的工作中,公鑰注冊(cè)和本人身份認(rèn)證這一部分可以由注冊(cè)機(jī)構(gòu)(Registration Authority,RA) 來(lái)分擔(dān)。這樣一來(lái),認(rèn)證機(jī)構(gòu)就可以將精力集中到頒發(fā)證書(shū)上,從而減輕了認(rèn)證機(jī)構(gòu)的負(fù)擔(dān)。不過(guò),引入注冊(cè)機(jī)構(gòu)也有弊端,比如說(shuō)認(rèn)證機(jī)構(gòu)需要對(duì)注冊(cè)機(jī)構(gòu)本身進(jìn)行認(rèn)證,而且隨著組成要素的增加,溝通過(guò)程也會(huì)變得復(fù)雜,容易遭受攻擊的點(diǎn)也會(huì)增。
倉(cāng)庫(kù)
倉(cāng)庫(kù)(repository)是一個(gè)保存證書(shū)的數(shù)據(jù)庫(kù),PKI用戶在需要的時(shí)候可以從中獲取證書(shū).它的作用有點(diǎn)像打電話時(shí)用的電話本。在本章開(kāi)頭的例子中,盡管沒(méi)特別提到,但Alice獲取Bob的證書(shū)時(shí),就可以使用倉(cāng)庫(kù)。倉(cāng)庫(kù)也叫作證書(shū)目錄。
8.3.3 各種各樣的PKI
公鑰基礎(chǔ)設(shè)施(PKI)這個(gè)名字總會(huì)引起一些誤解,比如說(shuō)“面向公眾的權(quán)威認(rèn)證機(jī)構(gòu)只有一個(gè)",或者“全世界的公鑰最終都是由一個(gè)根CA來(lái)認(rèn)證的",其實(shí)這些都是不正確的。認(rèn)證機(jī)構(gòu)只要對(duì)公鑰進(jìn)行數(shù)字簽名就可以了,因此任何人都可以成為認(rèn)證機(jī)構(gòu),實(shí)際上世界上已經(jīng)有無(wú)數(shù)個(gè)認(rèn)證機(jī)構(gòu)了。
國(guó)家、地方政府、醫(yī)院、圖書(shū)館等公共組織和團(tuán)體可以成立認(rèn)證機(jī)構(gòu)來(lái)實(shí)現(xiàn)PKI,公司也可以出于業(yè)務(wù)需要在內(nèi)部實(shí)現(xiàn)PKI,甚至你和你的朋友也可以以實(shí)驗(yàn)為目的來(lái)構(gòu)建PKI。
在公司內(nèi)部使用的情況下,認(rèn)證機(jī)構(gòu)的層級(jí)可以像上一節(jié)中一樣和公司的組織層級(jí)一一對(duì)應(yīng),也可以不一一對(duì)應(yīng)。例如,如果公司在東京、大阪、北海道和九州都成立了分公司,也可以采取各個(gè)分公司之間相互認(rèn)證的結(jié)構(gòu)。在認(rèn)證機(jī)構(gòu)的運(yùn)營(yíng)方面,可以購(gòu)買(mǎi)用于構(gòu)建PKI的軟件產(chǎn)品由自己公司運(yùn)營(yíng),也可以使用VeriSign等外部認(rèn)證服務(wù)。具體要采取怎樣的方式,取決于目的和規(guī)模,并沒(méi)有一定之規(guī)。
9. SSL/TLS
"SSL/TLS --- 為了更安全的通信"
本章中我們將學(xué)習(xí)SSL/TLS的相關(guān)知識(shí)。
SSL/TLS是世界上應(yīng)用最廣泛的密碼通信方法。比如說(shuō),當(dāng)在網(wǎng)上商城中輸人信用卡號(hào)時(shí),我們的Web瀏覽器就會(huì)使用SSL/TLS進(jìn)行密碼通信。使用SSL/TLS可以對(duì)通信對(duì)象進(jìn)行認(rèn)證,還可以確保通信內(nèi)容的機(jī)密性。
SSL/TLS中綜合運(yùn)用了之前所學(xué)習(xí)的對(duì)稱密碼、消息認(rèn)證碼、公鑰密碼、數(shù)字簽名、偽隨機(jī)數(shù)生成器等密碼技術(shù),大家可以在閱讀本章內(nèi)容的同時(shí)對(duì)這些技術(shù)進(jìn)行復(fù)習(xí)。嚴(yán)格來(lái)說(shuō),SSL(Secure Socket Layer)與TLS(Transport Layer Security)是不同的,TLS相當(dāng)于是SSL的后續(xù)版本。不過(guò),本章中所介紹的內(nèi)容,大多是SSL和TLS兩者兼?zhèn)涞?,因此除具體介紹通信協(xié)議的部分以外,都統(tǒng)一寫(xiě)作SSL/TLS。
9.1 客戶端與服務(wù)器
Bob書(shū)店是Alice經(jīng)常光顧的一家網(wǎng)店,因?yàn)樵贐ob書(shū)店她可以搜索到新出版的圖書(shū),還可以通過(guò)信用卡快速完成支付,購(gòu)買(mǎi)的書(shū)還能快遞到家,真的很方便。
有一天,Alice 讀了一本關(guān)于網(wǎng)絡(luò)信息安全的書(shū),書(shū)上說(shuō)“互聯(lián)網(wǎng)上傳輸?shù)臄?shù)據(jù)都是可以被竊聽(tīng)的"。Alice感到非常擔(dān)心,自己在購(gòu)買(mǎi)新書(shū)的時(shí)候輸人的信用卡號(hào)會(huì)不會(huì)被竊聽(tīng)呢?
Alice看到Bob書(shū)店的網(wǎng)站下面寫(xiě)著一行字:“在以https://開(kāi)頭的網(wǎng)頁(yè)中輸人的信息將通過(guò)SSL/TLS發(fā)送以確保安全"。
的確,輸人信用卡號(hào)的網(wǎng)頁(yè)的URL是以 https:// 開(kāi)頭的,而不是一般的 http://。此外.在瀏覽這個(gè)網(wǎng)頁(yè)時(shí),Alice的web瀏覽器上還會(huì)顯示一個(gè)小鎖頭的圖標(biāo),看上去好像挺安全的。
但Alice心想,就算寫(xiě)著“通過(guò)SSL/TLS發(fā)送”我也不放心啊,到底在我的Web瀏覽器和Bob書(shū)店的網(wǎng)站之間都發(fā)生了哪些事呢?
本章將要介紹的技術(shù)一一SSL/TLS就可以解答Alice的疑問(wèn)。當(dāng)進(jìn)行SSL/TLS通信時(shí),Web瀏覽器上就會(huì)顯示一個(gè)小鎖頭的圖標(biāo)。
**Alice的Web瀏覽器(客戶端)和Bob書(shū)店的網(wǎng)站(服務(wù)器)進(jìn)行HTTP通信**

Alice和Bob書(shū)店之間的通信,實(shí)際上是Alice所使用的Web瀏覽器和Bob書(shū)店的Web服務(wù)器之間的通信。Web瀏覽器是Alice的計(jì)算機(jī)上運(yùn)行的一個(gè)程序,而web服務(wù)器則是在Bob書(shū)店的計(jì)算機(jī)上運(yùn)行的一個(gè)程序,它們都遵循一種叫作HTTP(Hyper Text Transfer Protocol, 超文本傳輸協(xié)議)的協(xié)議(protocol)來(lái)進(jìn)行通信。其中,Web瀏覽器稱為HTTP客戶端,Web服務(wù)器稱為HTTP服務(wù)器。
當(dāng)Alice點(diǎn)擊網(wǎng)頁(yè)上的鏈接或者輸人URL時(shí),Web瀏覽器就會(huì)通過(guò)網(wǎng)絡(luò)向Web服務(wù)器發(fā)送一個(gè) “我要瀏覽這個(gè)網(wǎng)頁(yè)“,的請(qǐng)求(request)。
Web服務(wù)器則將請(qǐng)求的網(wǎng)頁(yè)內(nèi)容發(fā)送給Web瀏覽器,以便對(duì)請(qǐng)求作出響應(yīng)(response)。服務(wù)器和客戶端之間所進(jìn)行的處理就是請(qǐng)求和響應(yīng)的往復(fù)。HTTP可以認(rèn)為是在HTTP客戶端與HTTP服務(wù)器之間進(jìn)行請(qǐng)求和響應(yīng)的規(guī)范。
Alice向Bob書(shū)店發(fā)送信用卡號(hào)也是使用HTTP來(lái)完成的(下圖)。Alice輸人信用卡號(hào)之后按下提交按鈕,這時(shí)客戶端(Web瀏覽器)就會(huì)將信用卡號(hào)作為HTTP請(qǐng)求發(fā)送給服務(wù)器。服務(wù)器則會(huì)將“生成訂單"的網(wǎng)頁(yè)作為HTTP響應(yīng)返回給客戶端。
不過(guò),如果直接發(fā)送請(qǐng)求的話,信用卡號(hào)就很可能被竊聽(tīng)。下一節(jié)我們將探討針對(duì)這種風(fēng)險(xiǎn)的對(duì)策。
**不使用SSL/TLS發(fā)送信用卡號(hào)的情形**

9.2 用SSL/TLS承載HTTP
什么是SSL,什么是TLS呢?官話說(shuō)SSL是安全套接層(secure sockets layer),TLS是SSL的繼任者,叫傳輸層安全(transport layer security)。說(shuō)白點(diǎn),就是在明文的上層和TCP層之間加上一層加密,這樣就保證上層信息傳輸?shù)陌踩H鏗TTP協(xié)議是明文傳輸,加上SSL層之后,就有了雅稱HTTPS。它存在的唯一目的就是保證上層通訊安全的一套機(jī)制。
當(dāng)Web瀏覽器發(fā)送信用卡號(hào)時(shí),信用卡號(hào)的數(shù)據(jù)會(huì)作為客戶端請(qǐng)求發(fā)送給服務(wù)器。如果通信內(nèi)容被竊聽(tīng)者Eve所竊取,Eve就會(huì)得到信用卡號(hào)。
于是,我們可以用SSL(Secure Socket Layer)或者TLS(Transport Layer Security)作為對(duì)通信進(jìn)行加密的協(xié)議,然后在此之上承載HTTP(下圖)。通過(guò)將兩種協(xié)議進(jìn)行疊加,我們就可以對(duì)HTTP的通信(請(qǐng)求和響應(yīng))進(jìn)行加密,從而防止竊聽(tīng)。通過(guò)SSL/TLS進(jìn)行通信時(shí),URL不是以http://開(kāi)頭,而是以https://開(kāi)頭。
以上就是SSL/TLS的簡(jiǎn)單介紹。

在大致了解了SSL/TLS之后,我們來(lái)整理一下SSL/TLS到底負(fù)責(zé)哪些工作。我們想要實(shí)現(xiàn)的是,通過(guò)本地的瀏覽器訪問(wèn)網(wǎng)絡(luò)上的web服務(wù)器,并進(jìn)行安全的通信。用上邊的例子來(lái)說(shuō)就是,Alice希望通過(guò)web瀏覽器向Bob書(shū)店發(fā)送信用卡號(hào)。在這里,我們有幾個(gè)必須要解決的問(wèn)題。
- Alice的信用卡號(hào)和地址在發(fā)送到Bob書(shū)店的過(guò)程中不能被竊聽(tīng)。
- Alice的信用卡號(hào)和地址在發(fā)送到Bob書(shū)店的過(guò)程中不能被篡改。
- 確認(rèn)通信對(duì)方的Web服務(wù)器是真正的Bob書(shū)店。
在這里,(1)是機(jī)密性的問(wèn)題;(2)是完整性的問(wèn)題;而(3)則是認(rèn)證的問(wèn)題。
要確保機(jī)密性,可以使用對(duì)稱加密。由于對(duì)稱加密算法的密鑰不能被攻擊者預(yù)測(cè),因此我們使用偽隨機(jī)數(shù)生成器來(lái)生成密鑰。若要將對(duì)稱加密的密鑰發(fā)送給通信對(duì)象,可以使用非對(duì)稱加密算法完成密鑰交換。要識(shí)別篡改,對(duì)數(shù)據(jù)進(jìn)行認(rèn)證,可以使用消息認(rèn)證碼。消息認(rèn)證碼是使用單向散列函數(shù)來(lái)實(shí)現(xiàn)的。
要對(duì)通信對(duì)象進(jìn)行認(rèn)證,可以使用對(duì)公鑰加上數(shù)字簽名所生成的證書(shū)。
好,工具已經(jīng)找齊了,下面只要用一個(gè)“框架”(framework)將這些工具組合起來(lái)就可以了。SSL/TIS協(xié)議其實(shí)就扮演了這樣一種框架的角色。
SSL/TLS也可以保護(hù)其他的協(xié)議
剛才我們提到用SSL/TLS承載HTTP通信,這是因?yàn)镠TTP是一種很常用的協(xié)議。其實(shí)SSL/TLS上面不僅可以承載HTTP,還可以承載其他很多協(xié)議。例如,發(fā)送郵件時(shí)使用的SMTP(Simple Mail Transfer Protocol, 簡(jiǎn)單郵件傳輸協(xié)議)和接收郵件時(shí)使用的POP3(Post Office Protocol,郵局協(xié)議)都可以用SSL/TLS進(jìn)行承載。在這樣的情況下,SSL/TLS就可以對(duì)收發(fā)的郵件進(jìn)行保護(hù)。
用SSL/TLS承載HTTP、SMTP和POP3的結(jié)構(gòu)如下圖所示。一般的電子郵件軟件都可以完成發(fā)送和接收郵件這兩種操作,其實(shí)是同時(shí)扮演了SMTP客戶端和POP3客戶端這兩種角色。

9.3 https
9.3.1 http和https
HTTP協(xié)議:是互聯(lián)網(wǎng)上應(yīng)用最為廣泛的一種網(wǎng)絡(luò)協(xié)議,是一個(gè)客戶端和服務(wù)器端請(qǐng)求和應(yīng)答的標(biāo)準(zhǔn)(TCP),用于從WWW服務(wù)器傳輸超文本到本地瀏覽器的傳輸協(xié)議,它可以使瀏覽器更加高效,使網(wǎng)絡(luò)傳輸減少。
HTTPS:是以安全為目標(biāo)的HTTP通道,簡(jiǎn)單講是HTTP的安全版,即HTTP下加入SSL/TLS層,HTTPS的安全基礎(chǔ)是SSL/TLS,因此加密的詳細(xì)內(nèi)容就需要SSL/TLS。
<font color="red">HTTPS協(xié)議的主要作用可以分為兩種:</font>
- <font color="red">建立一個(gè)信息安全通道,來(lái)保證數(shù)據(jù)傳輸?shù)陌踩?lt;/font>
- <font color="red">確認(rèn)網(wǎng)站的真實(shí)性。</font>
HTTPS和HTTP的區(qū)別主要如下:
1、https協(xié)議需要到ca申請(qǐng)證書(shū),一般免費(fèi)證書(shū)較少,因而需要一定費(fèi)用。
2、http是超文本傳輸協(xié)議,信息是明文傳輸,https則是具有安全性的ssl/tls加密傳輸協(xié)議。
3、http和https使用的是完全不同的連接方式,用的端口也不一樣,前者是80,后者是443。
4、http的連接很簡(jiǎn)單,是無(wú)狀態(tài)的;HTTPS協(xié)議是由SSL/TLS+HTTP協(xié)議構(gòu)建的可進(jìn)行加密傳輸、
身份認(rèn)證的網(wǎng)絡(luò)協(xié)議,比http協(xié)議安全。
9.3.2 https優(yōu)缺點(diǎn)
-
https的優(yōu)點(diǎn)
盡管HTTPS并非絕對(duì)安全,掌握根證書(shū)的機(jī)構(gòu)、掌握加密算法的組織同樣可以進(jìn)行中間人形式的攻擊,但HTTPS仍是現(xiàn)行架構(gòu)下最安全的解決方案,主要有以下幾個(gè)好處:
- 使用HTTPS協(xié)議可認(rèn)證用戶和服務(wù)器,確保數(shù)據(jù)發(fā)送到正確的客戶機(jī)和服務(wù)器;
- HTTPS協(xié)議是由SSL+HTTP協(xié)議構(gòu)建的可進(jìn)行加密傳輸、身份認(rèn)證的網(wǎng)絡(luò)協(xié)議,要比http協(xié)議安全,可防止數(shù)據(jù)在傳輸過(guò)程中不被竊取、改變,確保數(shù)據(jù)的完整性。
- HTTPS是現(xiàn)行架構(gòu)下最安全的解決方案,雖然不是絕對(duì)安全,但它大幅增加了中間人攻擊的成本。
- 谷歌曾在2014年8月份調(diào)整搜索引擎算法,并稱 “比起同等HTTP網(wǎng)站,采用HTTPS加密的網(wǎng)站在搜索結(jié)果中的排名將會(huì)更高”。
-
https的缺點(diǎn)
雖然說(shuō)HTTPS有很大的優(yōu)勢(shì),但其相對(duì)來(lái)說(shuō),還是存在不足之處的:
- HTTPS協(xié)議握手階段比較費(fèi)時(shí),會(huì)使頁(yè)面的加載時(shí)間延長(zhǎng)近50%,增加10%到20%的耗電;
- HTTPS連接緩存不如HTTP高效,會(huì)增加數(shù)據(jù)開(kāi)銷(xiāo)和功耗,甚至已有的安全措施也會(huì)因此而受到影響;
- SSL/TLS證書(shū)需要錢(qián),功能越強(qiáng)大的證書(shū)費(fèi)用越高,個(gè)人網(wǎng)站、小網(wǎng)站沒(méi)有必要一般不會(huì)用。
- SSL/TLS證書(shū)通常需要綁定IP,不能在同一IP上綁定多個(gè)域名,IPv4資源不可能支撐這個(gè)消耗。
- HTTPS協(xié)議的加密范圍也比較有限,在黑客攻擊、拒絕服務(wù)攻擊、服務(wù)器劫持等方面幾乎起不到什么作用。最關(guān)鍵的,SSL證書(shū)的信用鏈體系并不安全,特別是在某些國(guó)家可以控制CA根證書(shū)的情況下,中間人攻擊一樣可行。
參考資料
PKCS15個(gè)標(biāo)準(zhǔn)
PKCS 全稱是 Public-Key Cryptography Standards ,是由 RSA 實(shí)驗(yàn)室與其它安全系統(tǒng)開(kāi)發(fā)商為促進(jìn)公鑰密碼的發(fā)展而制訂的一系列標(biāo)準(zhǔn)。
可以到官網(wǎng)上看看 What is PKCS
PKCS 目前共發(fā)布過(guò) 15 個(gè)標(biāo)準(zhǔn):
- PKCS#1:RSA加密標(biāo)準(zhǔn)。==PKCS#1定義了RSA公鑰函數(shù)的基本格式標(biāo)準(zhǔn),特別是數(shù)字簽名==。它定義了數(shù)字簽名如何計(jì)算,包括待簽名數(shù)據(jù)和簽名本身的格式;它也定義了PSA公/私鑰的語(yǔ)法。
- PKCS#2:涉及了RSA的消息摘要加密,這已被并入PKCS#1中。
- PKCS#3:Diffie-Hellman密鑰協(xié)議標(biāo)準(zhǔn)。PKCS#3描述了一種實(shí)現(xiàn)Diffie- Hellman密鑰協(xié)議的方法。
- PKCS#4:最初是規(guī)定RSA密鑰語(yǔ)法的,現(xiàn)已經(jīng)被包含進(jìn)PKCS#1中。
- PKCS#5:基于口令的加密標(biāo)準(zhǔn)。PKCS#5描述了使用由口令生成的密鑰來(lái)加密8位位組串并產(chǎn)生一個(gè)加密的8位位組串的方法。PKCS#5可以用于加密私鑰,以便于密鑰的安全傳輸(這在PKCS#8中描述)。
- PKCS#6:擴(kuò)展證書(shū)語(yǔ)法標(biāo)準(zhǔn)。PKCS#6定義了提供附加實(shí)體信息的X.509證書(shū)屬性擴(kuò)展的語(yǔ)法(當(dāng)PKCS#6第一次發(fā)布時(shí),X.509還不支持?jǐn)U展。這些擴(kuò)展因此被包括在X.509中)。
- PKCS#7:密碼消息語(yǔ)法標(biāo)準(zhǔn)。PKCS#7為使用密碼算法的數(shù)據(jù)規(guī)定了通用語(yǔ)法,比如數(shù)字簽名和數(shù)字信封。PKCS#7提供了許多格式選項(xiàng),包括未加密或簽名的格式化消息、已封裝(加密)消息、已簽名消息和既經(jīng)過(guò)簽名又經(jīng)過(guò)加密的消息。
- PKCS#8:私鑰信息語(yǔ)法標(biāo)準(zhǔn)。PKCS#8定義了私鑰信息語(yǔ)法和加密私鑰語(yǔ)法,其中私鑰加密使用了PKCS#5標(biāo)準(zhǔn)。
- PKCS#9:可選屬性類(lèi)型。PKCS#9定義了PKCS#6擴(kuò)展證書(shū)、PKCS#7數(shù)字簽名消息、PKCS#8私鑰信息和PKCS#10證書(shū)簽名請(qǐng)求中要用到的可選屬性類(lèi)型。已定義的證書(shū)屬性包括E-mail地址、無(wú)格式姓名、內(nèi)容類(lèi)型、消息摘要、簽名時(shí)間、簽名副本(counter signature)、質(zhì)詢口令字和擴(kuò)展證書(shū)屬性。
- PKCS#10:證書(shū)請(qǐng)求語(yǔ)法標(biāo)準(zhǔn)。PKCS#10定義了證書(shū)請(qǐng)求的語(yǔ)法。證書(shū)請(qǐng)求包含了一個(gè)唯一識(shí)別名、公鑰和可選的一組屬性,它們一起被請(qǐng)求證書(shū)的實(shí)體簽名(證書(shū)管理協(xié)議中的PKIX證書(shū)請(qǐng)求消息就是一個(gè)PKCS#10)。
- PKCS#11:密碼令牌接口標(biāo)準(zhǔn)。PKCS#11或“Cryptoki”為擁有密碼信息(如加密密鑰和證書(shū))和執(zhí)行密碼學(xué)函數(shù)的單用戶設(shè)備定義了一個(gè)應(yīng)用程序接口(API)。智能卡就是實(shí)現(xiàn)Cryptoki的典型設(shè)備。注意:Cryptoki定義了密碼函數(shù)接口,但并未指明設(shè)備具體如何實(shí)現(xiàn)這些函數(shù)。而且Cryptoki只說(shuō)明了密碼接口,并未定義對(duì)設(shè)備來(lái)說(shuō)可能有用的其他接口,如訪問(wèn)設(shè)備的文件系統(tǒng)接口。
- PKCS#12:個(gè)人信息交換語(yǔ)法標(biāo)準(zhǔn)。PKCS#12定義了個(gè)人身份信息(包括私鑰、證書(shū)、各種秘密和擴(kuò)展字段)的格式。PKCS#12有助于傳輸證書(shū)及對(duì)應(yīng)的私鑰,于是用戶可以在不同設(shè)備間移動(dòng)他們的個(gè)人身份信息。
- PDCS#13:橢圓曲線密碼標(biāo)準(zhǔn)。PKCS#13標(biāo)準(zhǔn)當(dāng)前正在完善之中。它包括橢圓曲線參數(shù)的生成和驗(yàn)證、密鑰生成和驗(yàn)證、數(shù)字簽名和公鑰加密,還有密鑰協(xié)定,以及參數(shù)、密鑰和方案標(biāo)識(shí)的ASN.1語(yǔ)法。
- PKCS#14:偽隨機(jī)數(shù)產(chǎn)生標(biāo)準(zhǔn)。PKCS#14標(biāo)準(zhǔn)當(dāng)前正在完善之中。為什么隨機(jī)數(shù)生成也需要建立自己的標(biāo)準(zhǔn)呢?PKI中用到的許多基本的密碼學(xué)函數(shù),如密鑰生成和Diffie-Hellman共享密鑰協(xié)商,都需要使用隨機(jī)數(shù)。然而,如果“隨機(jī)數(shù)”不是隨機(jī)的,而是取自一個(gè)可預(yù)測(cè)的取值集合,那么密碼學(xué)函數(shù)就不再是絕對(duì)安全了,因?yàn)樗娜≈当幌抻谝粋€(gè)縮小了的值域中。因此,安全偽隨機(jī)數(shù)的生成對(duì)于PKI的安全極為關(guān)鍵。
- PKCS#15:密碼令牌信息語(yǔ)法標(biāo)準(zhǔn)。PKCS#15通過(guò)定義令牌上存儲(chǔ)的密碼對(duì)象的通用格式來(lái)增進(jìn)密碼令牌的互操作性。在實(shí)現(xiàn)PKCS#15的設(shè)備上存儲(chǔ)的數(shù)據(jù)對(duì)于使用該設(shè)備的所有應(yīng)用程序來(lái)說(shuō)都是一樣的,盡管實(shí)際上在內(nèi)部實(shí)現(xiàn)時(shí)可能所用的格式不同。PKCS#15的實(shí)現(xiàn)扮演了翻譯家的角色,它在卡的內(nèi)部格式與應(yīng)用程序支持的數(shù)據(jù)格式間進(jìn)行轉(zhuǎn)換。





