關鍵字:密碼學,密碼算法,單向哈希函數,對稱加密,非對稱加密,數字簽名,數字證書,Merkle樹,同態加密
在計算機科學中,密碼學常常用來解決某些特定的難題:
- 文件機密性,對於某些需要保密的文件的加密工作。
- 鑒別真偽,也叫認證,防止文件被偽造。
- 驗證完整性,驗證文件的完整性,傳輸中是否有破損。
- 信用問題,也即不可抵賴性,這也是區塊鏈要解決的關鍵問題,對於所有人的信用問題,那些承諾算不算數。
密碼學可以細分為密碼協議,密碼技術以及密碼算法,本文不會詳盡學習密碼學的所有角落,而是專門針對區塊鏈應用到的密碼學知識進行學習。
密碼算法
單向哈希函數
博主曾在查找算法那一章中詳細地從數據結構原理分析了哈希算法。哈希算法在密碼學中有着非常重要的位置,是很多密碼算法的基礎。它可以將任意長度的二進制明文映射為較短的(通常為固定長度的)二進制串(Hash值),並且不同的明文很難映射為相同的哈希值(如果不同的明文映射為相同的哈希值了,就出現了碰撞,在查找算法那篇文章里面都做了詳盡的分析。)所以,理想狀態下,一個優秀的單向哈希函數包含以下幾個特點:
- 正向快速:能夠快速計算出給定明文映射的哈希值。
- 逆向困難:很難通過一個哈希值來反推出它的明文。
- 輸入敏感:明文修改了哪怕一個字符,映射的哈希值可能有很大改動。
- 沖突避免:不能發生碰撞。
實際上,單向哈希函數在密碼學中還有很多種名字:壓縮函數、收縮函數、消息摘要、指紋、密碼校驗和、信息完整性檢驗、操作檢驗碼。
單向哈希函數的使用方法,通常都是一方對自己的明文進行映射得到哈希值,然后與另一方傳過來的哈希值進行比對,如果一致,則說明兩方的原文一致。
在這種操作過程中,明文不會涉及到數據傳輸,傳輸的是哈希值,這就對數據進行了有效的保護。
常見算法
密碼學中常見的單向哈希算法有:
- MD4,已淘汰
- MD5,MD4的升級版,但是對於任意明文的哈希值碰撞,還是無法達到百分百。
- SHA,是一套哈希函數族,SHA-1已被淘汰,升級后的SHA-2包含SHA-224、SHA-256、SHA-384、SHA-512。
以上單向哈希算法中,推薦使用SHA-256。
單向哈希函數可以說是對原文的一種隱蔽或者混淆,常用於對口令的保存。例如用戶登錄網站需要通過用戶名密碼的驗證,網站后台就可以通過單向哈希函數來保存密碼的哈希值,及時被竊聽者偷到數據,他也無法直接推出密碼的原文是什么。
風險與防御
然而,現今網站太多,用戶往往不具備很高的安全意識,所以很有可能他們的多個網站上面都采用相同的密碼,並且這個密碼本身的強度也不夠,有人專門收集了這些常見密碼,計算出對應的哈希值放在一個字典里面。這樣通過哈希值可以快速比對出密碼原文。這種空間換時間的攻擊方法被稱為字典攻擊,有人升級了字典攻擊,只保存一條哈希值的首位值,相對字典攻擊節省了大量空間,升級后的字典攻擊被稱為彩虹表攻擊。
那么針對字典攻擊以及彩虹表攻擊,網站是否有有效的防御手段呢?
最有效的防御手段就是加鹽(salt),即網站數據庫保存的不是僅將密碼映射出來的哈希值,而是密碼明文再加上一段隨機字符串(鹽)之后的哈希值,同時將“鹽”單獨保存,這樣一來字典里的哈希值就不再具備廣泛性,從而也就失去了它的攻擊能力。
對稱加密
單向哈希函數其實不算加密算法,因為它不能真正地對信息進行保護,它只能對數據進行哈希映射但不能翻譯出原文。下面我們來介紹真正的加密算法技術,首先就是對稱加密。
對稱加密,就是加解密使用的密鑰相同。
在單向哈希函數中,是沒有密鑰這個概念的,這也是它無法成為加密算法的原因之一。
如果把對稱算法看成保險櫃,密鑰就是保險櫃的號碼組合。知道號碼組合的人能夠打開保險櫃,放入文件,再關閉它,然后另一個也知道號碼組合的人可以打開保險櫃,取出文件。
常見算法
對稱加密算法的計算效率高,加密強度高,所以它適用於大量數據的加解密過程,但是缺陷是它必須提前將密鑰共享出去,這期間一旦泄露則文件無加密可言。對稱加密算法有DES,3DES,AES,IDEA。
對稱加密算法推薦使用AES和IDEA。
風險與防御
針對對稱加密,通常會采用選擇密文攻擊,它是指竊聽者任意收集一定量的密文信息,讓這些密文通過自己嘗試的一些加密算法來解密獲得明文,一旦嘗試成功,竊聽者可以在不知道密鑰的情況下即可獲得真正有效數據的明文信息。
有效辦法是將明文信息先用單向哈希函數處理以后再進行加密傳輸,這樣一來,竊聽者即使試出了加密算法也無法對解密明文進行解析。
非對稱加密
非對稱加密是在對稱加密之后誕生的算法,也叫做公開密鑰算法,顧名思義,它的加密密鑰和解密密鑰是不同的,分別稱為公鑰和私鑰。非對稱加密算法要先通過隨機數算法生成私鑰,然后通過私鑰生成公鑰,將公鑰公開出去,任何人都可以拿到公鑰對數據進行加密,然而只有少部分持有結對私鑰的人才能將文件解密。
常見算法
非對稱算法解決了密鑰泄露的問題,但是它的加解密過程要比對稱算法慢上幾個數量級,同時加密強度也不如對稱加密。非對稱加密算法包括RSA、EIGamal、橢圓曲線、SM2等系列算法。
其中橢圓曲線又叫ECC算法,是當前比較推薦采用的非對稱加密算法,另外SM2也可以。
風險與防御
針對非對稱加密,通常會采用選擇明文攻擊。由於非對稱加密公鑰是公開的,竊聽者就可以任意構造一個明文進行加密得到加密串,通過不斷的嘗試,竊聽者可以掌握加密算法的一些信息,以方便日后破解同樣加密算法加密的信息,最壞情況下,竊聽者甚至可以直接獲得解密的私鑰。
現在的RSA和ECC已經具備了一定的保護機制來避免這種攻擊風險,手段就是對同樣的明文使用同樣的密鑰進行多次加密,得到的結果卻完全不同,這就給竊聽者試圖從加密串中獲得規律帶來了難度,避免了選擇明文攻擊。
混合加密機制
其實上面針對選擇明文攻擊和選擇密文攻擊的處理方案都是混合加密機制的思想。混合加密機制結合了對稱加密和非對稱加密的優點。
簡單來講,明文是靠對稱加密算法加解密的,但是對稱加密的密鑰K是通過非對稱加密進行發放,K通過公鑰加密后的串是公開的,授權人必須通過自己持有的私鑰來解密K,再用K來解密密文。
HTTPS協議
舉一個非常經典的例子就是HTTPS協議,它是基於HTTP協議,更加安全的協議,現已成為最普遍的web通訊協議。它定義的交互過程為:
- 客戶端瀏覽器發送明文信息到服務器,信息包括:隨機數R1,建議加密類型,建議壓縮算法,支持協議的最高版本。
- 服務端返回明文信息,包括:選定協議版本,選定加密類型,選定壓縮算法,隨機數R2。
- 客戶端檢查自身證書系統尋找該網站公鑰,該證書是通過第三方CA來簽發。
- 證書沒問題,客戶端拿到該網站公鑰,加密隨機數R3發送給服務端。
- 服務端通過自身私鑰解密獲得隨機數R3。此時,客戶端和服務端都有了R1,R2,R3。
- 客戶端和服務端均通過一個偽隨機函數(參數一致結果則一致,並不是真隨機),參數為R1,R2,R3,獲得會話密鑰MasterSecret。
- 通過會話密鑰MasterSecret,客戶端和服務端的通信都通過對稱加密算法進行保護。
以上則是細致地分析了HTTPS協議的每個步驟的工作內容,可以看出,在保護對稱算法密鑰的這條路上,HTTPS真是不遺余力:它通過2個明文隨機數加上一個非對稱加密算法保護的隨機數R3,在此基礎上,將三個隨機數進行了函數處理才得到最終的對稱算法的密鑰。即使外界知道加密協議版本,加密類型,壓縮算法和前2個隨機數,他們也不知道R3是多少,也就無法得知那個偽隨機函數是怎么寫的,所以會話密鑰得到了更深層次的保護,外界只能看到被會話密鑰加密后的密文,他們無法得知那個會話密鑰是什么。
安全技術
數字摘要
數字摘要是單向哈希函數最重要的一個用途,也可被稱為文件完整性測試。通過對原文進行哈希運算,獲得唯一的摘要值來指代原文,數字摘要解決了確保內容未被篡改過的問題。我們在從網絡上下載文件時,都會被提供一個數字摘要值,我們可以通過對下載到本地的文件進行運算得到本地摘要值,然后與網絡提供的進行對比,如果一致說明文件未被篡改,不一致說明有篡改過。
消息認證碼
全稱為“基於Hash的消息認證碼”,英文縮寫HMAC。
基本過程:對某個消息利用提前共享出來的對稱密鑰和Hash算法進行加密處理,得到HMAC值。該HMAC值持有方可以證明自己擁有共享的對稱密鑰,並且也可以利用HMAC確保消息內容未被篡改。
典型的HMAC包含三個因素(K,H,Message):
- K為提前共享的對稱密鑰。
- H為提前商定的Hash算法。
- Message為消息內容。
消息認證碼一般用於證明身份的場景。任何拿到K和H的授權人可以通過發送明文消息給另一方,另一方通過K,H,Message得到HMAC值返回前人,前面的人自己算出HMAC來比對,如果一致則說明是自己人,如果不一致則停止通信。
然而,得到K和H的授權人可能不止一個,對於其中一個人來說,其他所有的授權人都是一樣的,無法區分他們。這就引出了身份的進一步定義——數字簽名的技術。
數字簽名
數字簽名也有着簽名的效力,它是基於非對稱加密,既可證明某數字內容的完整性,又同時可以確認來源(或者作為證據,不可抵賴性),看上去它是以上兩種技術的匯總升級版,既有數字摘要的文件完整性校驗的功能,也有消息認證碼的更明確的身份確認。下面是幾點注意:
- 非對稱加密中,公鑰和私鑰是一對一生成的,因此某個身份只會擁有唯一的一對密鑰,與其他身份不同。
- 非對稱加密一般是公鑰加密,私鑰解密的,而數字簽名中是私鑰加密,公鑰解密。是因為簽名是為了外人確認我的身份,而外人只能看到公鑰,所以我需要用我自己的私鑰加密一串信息,外人拿到密文后用公鑰解密得到信息。
- 信息在用我的私鑰加密以前,為了獲得完整性功能加成,我要將信息做數字摘要,然后把摘要進行私鑰加密,這樣一來外人公鑰解密獲得的是數字摘要,通過比對數字摘要,一來可以確認我的身份,二來可以確定文件的完整。
常見數字簽名算法包括DSA和安全強度更高的ECDSA等。
注意:簽名只是為了確認身份和文件完整性,而不是為了傳輸文件,切記切記。
下面來談談數字簽名的安全性,它是由數學問題進行保障。目前常見的數字簽名算法往往需要選取何時的隨機數作為配置參數,配置參數不合理的使用或泄露都會造成安全漏洞,需要進行安全保護。之前索尼公司的PS3雖然采用了較為安全的ECDSA進行簽名,然而錯誤地使用了重復的隨機參數,最終導致私鑰被破解,造成經濟上的重大損失。
下面介紹幾種特殊的簽名類型:
盲簽名
在數字摘要之前的原始內容本身就是一個密文,作為簽名者的我無法看到原始內容,我只能將原始內容做摘要然后私鑰加密摘要進行簽名。外人通過找到對應我身份的公鑰解密簽名獲得摘要值比對確定我的身份以及文件完整性。而對於文件內容本身,我和外人都無從得知,因為從摘要是很難逆向得到明文的,而且得到的也是原始內容的密文,又不知道如何解密。
盲簽名實現了對原始內容的保護,防止簽名者看到原始內容,而且簽名者也無法將簽名內容和簽名結果進行對應。
典型的實現包括RSA的盲簽名算法等。
多重簽名
多重簽名規定了總共n個簽名者,收集到m個(n>=m>=1)簽名並判斷有效,則認為該文件合法。
多重簽名可以有效地被應用在多人投票共同決策的場景中。多重簽名的主要目的是在身份和文件完整性驗證的基礎上,由多人投票確認簽名文件本身是否合法。
比特幣交易中使用到的就是多重簽名機制,可實現多人共同管理某個賬戶的比特幣交易。也就是說當某個賬戶發生比特幣交易的時候,多個人去記錄這比交易形成交易文件,比特幣規定,每筆交易的文件的格式內容是有一個最終標准的,只不過多人在形成這個文件的過程中要克服一些數學問題(挖礦),當他們中有一人完成了交易文件就會對它進行簽名並廣播,其他人收到簽名以后會驗證,如果簽名沒有問題,則該文件合法,所以這里對應的多重簽名里的m值為1,有一個人的簽名通過了,就可證明該文件合法,然后會將該交易文件合到比特幣主區塊鏈上去。
群簽名
群簽名即某個群組內的一個成員可以代表群組進行匿名簽名。簽名可以驗證來自於該群組,卻無法准確追蹤到簽名的是哪個具體成員。
群簽名需要一個群管理員來添加新的群成員,因此存在群管理員可能追蹤到簽名成員身份的風險。
群組內的成員每人都有一個自己的私鑰,而對於外人來講,整個群組只有一個公鑰,外人可以通過公鑰來解密簽名,匹配一致這說明是該群組的簽名,然而該簽名是群組內的某個人通過自己唯一的私鑰進行的加密。類似於公鑰對私鑰是1對多的關系,真實的情況肯定還是一個公鑰對一個私鑰,那么這里的一對多是如何形成的呢?我想可能是對群組內的每個公鑰做了一個處理,將群組內的公鑰生成了一個統一的對外暴露的“群公鑰”。
環簽名
環簽名屬於一種簡化的群簽名。
簽名者首先選定一個臨時的簽名者集合,集合中包括簽名者自身。然后簽名者利用自己的私鑰和簽名集合中其他人的公鑰就可以獨立地產生簽名,而無需他人的幫助。簽名者集合中的其他成員可能並不知道自己被包含在最終的簽名中。
下面來分析一波,環簽名旨在某個簽名者想匿名簽名,他自己拉起來一個臨時的群組,他能夠獲得群組內其他人的公鑰,然后他用自己的私鑰加密了文件,通過一種手段,提供給外人解密的公鑰變成了其他人的公鑰,這就讓外人無法定位到簽名者本人。
環簽名在保護匿名性方面有很多的用途。
數字證書
對於非對稱加密算法和數字簽名來說,很重要的一點就是公鑰的分發。理論上任何人可以公開的拿到對方的私鑰。然而在這種前提下,如果竊聽者偽造了公鑰,在傳輸過程中對真實數據進行了釣魚篡改。一旦公鑰出了問題,整個安全體系也將隨之崩塌。因此維護公鑰的正確性是非常重要的。數字證書就是為了解決這個問題。
數字證書就可以證明某個公鑰是某個實體(或組織或個人)的,並且確保一旦篡改能被探測出來,從而實現對用戶公鑰的安全分發。
證書保護的公鑰分為兩種,上面我們也都介紹過了:
- 一個是非對稱加密中,用來加密的公鑰。
- 另一個是數字簽名中,用來驗證簽名的解密公鑰。
這兩種類型的公鑰也可同時放在一個證書中。
一般情況下,證書需要有證書認證機構(CA)來進行簽發和背書。權威的證書認證機構包括DigiCert、GlobalSign、VeriSign等。用戶也可以自行搭建本地CA系統,在私有網絡中進行使用。目前證書的規范均采用X.509證書規范,該規范中規定了證書所包含的信息,有版本號,序列化,簽名算法,頒發者,有效期,主體,主體的公鑰信息,頒發者唯一號,主體唯一號,擴展。此外,證書的頒發者還需要對證書內容利用自己的公鑰添加簽名,以防止別人對證書內容進行篡改。X.509規范推薦使用PEM格式來存儲證書相關文件。證書文件的文件名后綴一般為.crt或者.cer,對應私鑰文件的文件名后綴一般為.key,證書請求文件的文件名后綴為.csr。有時候也統一用.pem作為文件名后綴。PEM格式采用文本方式進行存儲,一般包括首尾標記和內容塊,內容塊采用Bash64進行編碼。
Merkle樹
Merkle樹,又叫哈希樹,是一種典型的二叉樹結構,由一個根結點、一組中間節點和一組葉節點組成。在區塊鏈系統出現之前,廣泛用於文件系統和P2P系統中。主要特點:
- 最下面的葉節點包含存儲數據或哈希值。
- 非葉子節點(包括中間節點和根結點)都是它的兩個孩子節點內容的哈希值。
Merkle樹可以推廣到多叉樹的情形,此時非葉子節點的內容為它所有的孩子節點內容的哈希值。Merkle樹逐層記錄哈希值的特點,讓它具有了一些獨特的性質。例如,底層數據的任何變動,都會傳遞到其父節點,一層層沿着路徑一直到樹根。這意味着樹根的值實際上代表了對底層所有數據的“數字摘要”。Merkle樹的應用場景有:
- 快速比較大量數據:對每組數據排序后構建Merkle樹結構。當兩個Merkle樹根相同時,兩組數據也必然相同。否則,必然存在不同。由於Hash計算的過程可以十分迅速,預處理可以在短時間內完成。利用Merkle樹結構能帶來巨大的比較性能優勢。
- 快速定位修改:如果一個節點的數據被修改,那么它的父節點,父節點的父節點直到根節點,會一路收到影響。因此,一旦發現根節點的數值發生變化,可以快速定位到實際發生改變的數據塊。
- 零知識證明:如何向他人證明擁有的某組數據中包括給定的某個內容D0而不暴露其他任何內容?可以使用Merkle樹,D0的擁有者通過驗證生成的根節點的數值是否與提供的值一致,即可很容易檢測提供者是否包含D0。而整個過程驗證者無法獲知其他內容。
同態加密
同態加密是一種特殊的加密方法,允許對密文進行處理得到仍然是加密的結果。即對密文直接進行處理,跟對明文進行處理后再對處理結果加密,得到的結果相同。從抽象代數的角度將,保持了同態性。
同態加密可以保證實現處理者無法訪問到數據自身的信息。
總結
本文簡單介紹了應用密碼學中區塊鏈相關的一些問題和算法。掌握這些知識,對於幫助理解區塊鏈系統如何實現隱私保護和安全防護都很有好處。區塊鏈技術中大量利用了現代密碼學的已有成果,包括Hash,加解密,簽名,Merkle樹數據結構等。另一方面,區塊鏈系統和諸多新的場景也對密碼學和安全技術提出了很多新的需求,反過來也將促進相關學科的進一步發展。
參考資料
- 應用密碼學(協議、算法與C源程序)
- 區塊鏈(原理、設計與應用)
