轉載聲明:本文來自微信公眾號:火龍果園長,僅供學習交流,禁止用于商業用途,轉載需關注公眾號取得文章作者同意。
寫在開頭
荀子曰:“人之性惡,其善者偽也”,意思就是說人性是惡的,這種惡是符合馬斯洛需求理論的。當你吃不飽的時候你去追求物質,當你有物質基礎后你去追求精神享受等等,并不是這種追求有什么問題,而是在追求的過程中總有那么一些人企圖通過不正當的手段去到達自己的目的,所謂的惡即是這種惡。我們不是為了剖析人性本惡,更不是探討馬斯洛需求理論,我們要討論的僅僅是如何防范這種惡,確切的說是如何通過密碼學方法防止這種惡,尤其是在區塊鏈中。
密碼學概念
在開始之前,我們總是偏向提出一個問題,然后針對這個問題給出答案,如果在解答過程中,出現了問題,我們再針對問題給出答案,不斷的填坑,讓最初的答案完美解決,并且不會引入其他的問題。同時我們為了讓密碼學更加“生活化”和“本土化”,不采用大家熟悉的Alice和Bob作為人設,而是用小明、小花和小黑代替,并且假定小明和小花在談戀愛,小黑是個腹黑的第三者,并且是一個郵遞員。故事開始!
1. 加密算法
小明和小花可以說青梅竹馬,兩小無猜,最近處于熱戀期。小明給小花寫了一封肉麻的情書,拜托小黑拿給小花。當小黑拿到情書后,覺得再這么下去肯定會失去小花,所以他打開了情書,研讀了每一句情話,然后心想:“我靠,原來小明是個衣冠禽獸,情書的內容如此不可描述”,并且當著全村人的的面宣讀了小明寫給小花的情書(明文形式),這讓小明一度無臉面對鄉親父老,小花也覺得很尷尬。小明痛定思痛,發明了一種方法,通過這種方法對內容進行了處理,即使小黑看了情書內容(密文形式)也不知道說的啥。我們把這個方法就叫加密算法,把處理過程叫加密。
在加密過程中涉及到一個重要概念,就是密鑰,它是一個參數,作為加密算法的輸入,同一個明文在相同的加密算法和不同的密鑰計算下產生不同的密文。目前很多知名的加密算法都是公開的,密鑰才是決定密文是否安全的重要參數,通常密鑰越長,破解的難度越大。
所以加密算法可以理解為:利用密鑰對明文內容進行特殊處理,并生成密文,同時根據密鑰也可以將密文轉化為明文的一種方法。
2. 對稱加密
那小明采用了什么加密算法呢?小明把每個漢字和數字對應起來,1代表我,2代表愛,3代表你,小明在信中寫到123,小黑一臉懵逼,完全不知道啥意思,可是當小花收到情書后,按照對應關系讀懂了小明的意思,臉上泛起了紅圈。我們把這個漢字和數字的對應規則叫做加密算法,而具體的對應關系叫做密鑰,比如你也可以用2代表我,3代表愛,4代表你。小明用來加密的密鑰和小花用來解密的密鑰是一樣的,我們把這種加密算法叫做對稱加密。
常見的對稱加密算法有DES、3DES、AES、RC5、RC6等。對稱加密的優點是計算速度快,但是需要通訊兩端共享密鑰,這樣會有三個問題:
- 密鑰在共享過程中存在被盜取風險;
- 如果所有客戶端共享一個密鑰,那么這個密鑰就是一個萬能鑰匙,啥都可以解密;
- 如果每個客戶端和服務端單獨維護一個密鑰,這樣會有成千上萬的密鑰,服務端對密鑰的管理將成為災難。
接著講故事,小黑也不是吃素的,他參透了其中的奧秘,并在小明和小花共享密鑰的過程中盜取了這份具體的映射表(密鑰),小明說啥肉麻的情話小黑都知道了。盡管小明和小花不停的更換新的加密方式,小黑都能弄到密鑰(趴門縫偷聽、讀唇語等),同時 ,小明不停的更換密鑰讓小花也很煩躁,有時候都不知道該用哪一個解密了,這讓小明和小花的感情一度出現了危機。
3. 非對稱加密
小明感受到了來自小花的壓力,又陷入了嬸嬸的沉思,怎么才能讓小黑這個傻X破解不了我們的情書呢?這個時候小花告訴小明,你歇一歇,讓我(服務端)來。小花的方法是這樣的,她生成了一對密鑰(公鑰和私鑰),公鑰可以破解通過私鑰加密的內容,私鑰可以破解公鑰加密的內容,是不是覺得太難理解了?舉個栗子:可以把公鑰或私鑰理解為一個保險箱加一把鑰匙,公鑰的保險箱可以用私鑰的鑰匙打開,而公鑰的鑰匙可以打開私鑰的保險箱,反之亦然。過程是這樣的:
- 小花生成了一對密鑰(公鑰和私鑰),并把私鑰(打開公鑰保險箱的鑰匙)保存在自己那邊,然后把公鑰發送給了小明(客戶端)
- 小明收到小花的公鑰后,把情書放進了公鑰的保險箱中(用公鑰加密),并把公鑰保險箱(通過公鑰加密的內容)發送給了小花
- 小花收到小明的內容后,用私鑰的鑰匙打開了公鑰的保險箱,并讀取了內容,臉上再一次泛起了紅圈
非對稱加密的特點很明顯:1)需要生成一對不同的密鑰(公鑰和私鑰);2)公鑰公開,私鑰保留;3)加密和解密的密鑰不同。目前常見的非對稱加密有RSA,DSA,ECC等。
非對稱加密比對稱加密更加安全,因為與對稱加密相比,非對稱加密無需在小明(客戶端)和小花(服務端)之間共享密鑰,只要私鑰不發給任何人,即使公鑰在網絡上被截獲,也無法解密。
tips:非對稱加密最重要的就是單向函數,即通過可以通過x可以輕易計算f(x),但知道f(x)不能輕易算出x。目前普遍采用歐拉定理作為單向函數,一個重要的common sense是:兩個大質數p和q,和容易求的p*q=N,但是知道N比較難求得p和q。
4. 數字簽名
由于小明采用了非對稱加密,小黑無法破解小明和小花之間的悄悄話,悶悶不樂了好幾天。所謂道高一尺,魔高一丈,小黑還是有幾把刷子的。他準備惡搞一把小明和小花。和往常一樣,小明給小花寫了一封情書,這封情書除過寫一些你儂我儂的話之外,還告訴小花七夕節兩個人約定去一趟杭州的斷橋,在游山轉水的同時模仿一下白娘子和許仙,鞏固一下兩人的感情。可是當小明把裝有情書的公鑰保險箱(用小花公鑰加密的情書內容)交給小黑后,小黑并沒有轉交給小花,而是自己寫了一封情書,情書的內容是清明節一起去給小花的爺爺上墳,并將偽造的情書放進小花的公鑰保險箱轉交給了小花。后果可想而知,小花把小明劈頭蓋臉的罵了一頓。
不過小花并沒有氣餒,她知道是小黑在情書內容上動了手腳。經過一個晚上的思考,她決定讓小明每次寫好情書之后,按一個手印,而且不同的內容要按照不同的姿勢按不同的手印。這個手印就叫數字簽名,這個手印有兩個目的:1)確保這封情書是小明寫的,而不是其他人;2)確保這封情書的內容沒有被人改動過。這樣小黑就沒辦法進行情書偽造了。
過程如下:
- 小明寫一份情書,然后對情書內容進行處理(SHA或MD)生成一個和情書內容對應的獨一無二的內容(摘要信息),然后對生成的內容(摘要)使用自己的私鑰加密生成手印(簽名),然后連同情書內容一起發給小花(服務端)
- 小花收到按了手印的情書后,把簽名取出來用小明的公鑰解密,如果能解密出來,說明是小明寫的情書
- 然后小花把情書內容取出來并進行同樣的處理(SHA或MD),得到一個獨一無二的內容(摘要),然后和情書中的通過解密得到的內容(摘要)進行比較,如果相同,說明情書沒有被改動,反之被改動。
數字簽名的目的有兩個:1)驗證請求或者數據發送方的身份;2)驗證發送的請求報文或數據內容是否被篡改。
5. 數字證書
小黑既不能破解也不能偽造小明寫給小花的情書,看啥都不順眼,打王大媽家的狗,偷李大媽家的貓,這都是小黑發泄的行為。不過,小黑并沒有放棄,天天捋思路:保險箱是小花給的,我沒有鑰匙打不開,情書內容是小明寫的,這孫子又套上了自己的手印,也沒辦法偽造,我拿到這兩個人的公鑰也沒用、沒用、用......咦?公鑰沒用?小黑腦子閃過一道靈光,發出了邪惡的笑聲。他并沒有對情書內容下手,而是在小花將公鑰通過公網發送給小明的時候,把小花的保險箱(公鑰)換成了自己的保險箱(公鑰),小明還不知情,把按了簽名的情書塞到了小黑的保險箱并交給了小黑,這還得了!小明不可描述的情書一次又一次的被大家當成反面教材,寫在了村頭的恥辱柱上。
小花又一次臭罵了小明,罵小明你眼睛瞎了鼻子都出問題了嗎:保險箱(公鑰)你分辨不出來?跟我這么長時間,保險箱(公鑰)上的體香你還分辨不出來嗎?小明心里有苦不知道向誰說,為了避免來自小花的一萬點暴擊,默默的朝村頭走去。就這這個時候,背后有人喊:老鄉等等。小明轉身一看是村里的張大爺,張大爺是村里的名人,不管什么事情,大家都喜歡喊上張大爺一起,小到母雞下蛋,大到紅白喜事。原因很簡單,張大爺在村里聲望和信譽很高,大家都很尊重和信任他。張大爺說:小伙子,你讓你你女朋友把她的保險箱(公鑰)放到我這邊做一下認證,我給他頒發一個證書,下次你們用我發的證書就可以了“,真的這么神奇嗎?小明決定嘗試一下:
- 小花(服務器)向張大爺(第三方CA機構)提交公鑰等信息申請認證
- 張大爺(第三方CA機構)通過各種方式驗明小花”正身“后,給小花簽發一個認證文件-證書
- 證書內容:申請者公鑰、申請者的組織信息和個人信息、簽發機構 CA 的信息、有效時間、證書序列號等信息的明文,同時包含一個簽名
- 簽名算法:首先,使用摘要生成函數(MD或SHA)計算公開的明文信息的信息摘要,然后,采用 CA 的私鑰對信息摘要進行加密,密文即簽名
- 小明又開始寫情書了,這次不需要小花的保險箱(公鑰)了,而是需要小花的證書
- 小花收到小明的請求后,把證書發給小明,小明采用同樣的摘要生成函數計算摘要,并利用對應的CA公鑰解密簽名數據,對比簽名信息摘要,如果一致,則合法
- 小明發情書給小花:
- 小明(客戶端)把情書放進證書中的保險箱(小花的公鑰),然后發送給小花,或者;
- 小明(客戶端)生成一個隨機數,把隨機數放進證書中的保險箱(小花的公鑰)發送給小花,小花解密得到隨機數。然后小明和小花使用隨機數作為鑰匙進行書信往來
所有的加密算法或者加密原則基本上都是基于上述概念,區塊鏈亦如此。
常用加密算法
1. 哈希算法
之所以把哈希算法單獨提出來進行說明,是因為哈希算法在區塊鏈中留下了濃重的一筆。密碼哈希函數是一類數學函數,可以在優先合理的時間內,將任意長度的消息壓縮為固定長度的二進制串,其輸出值成為哈希值,也稱為散列值。哈希算法常用于實現數據完整性(消息摘要)和實體認證(簽名),同時也構成多種密碼體系和協議的安全保障。
理解碰撞:所謂碰撞就是兩個不同的消息(情書)在同一個哈希函數作用下,具備相同的哈希值。哈希函數的安全性是指在現有的計算資源下,找到一個碰撞是不可行的。
目前流行的 Hash 算法包括 MD5、SHA-1 和 SHA-2。在比特幣系統中使用了兩個密碼學哈希函數,一個是SHA256、兩一個是RIPEMD160,其中RIPEMD160主要用于生成比特幣地址。
1.1 SHA256原理
SHA256是構造區塊鏈所用到的主要密碼哈希函數。對于長度小于2^64位的消息,SHA256會產生一個256位的消息摘要。
SHA256是一個Merkle-Damgard結構的迭代哈希函數,計算過程分為兩個階段:1)消息的預處理;2)主循環。在消息的預處理階段主要完成消息的填充和擴展填充,將所輸入的原始消息轉化為n個512比特的消息塊,之后對每個消息塊利用SHA256壓縮函數進行處理,如下圖所示,當最后一個消息塊處理完畢后,最終的輸出值就是所所輸入的原始消息的SHA256值。
1.2. 哈希的優秀品質
哈希函數具備的優秀品質如下:
- 抗碰撞性:所謂碰撞就是兩個不同的消息(情書)在不同的加密函數作用下,產生相同的密文。抗碰撞性,是指尋找兩個碰撞的消息在計算上不可行。不可行不代表不存在。在區塊鏈中SHA256被用來進行工作量證明,而哈希函數的抗碰撞性也常用來檢測區塊信息的完整性。
- 原相不可逆:這個之前也說了,就是通過輸入值,可以很容易通過哈希函數計算出哈希值,但是通過哈希值,沒有辦法計算出原來的輸入值
- 難題友好性:簡單的可以理解為劃定一個知道輸入的哈希值范圍,然后通過判斷哈希值是否落在該范圍內,從而推出輸入值。這種方法在哈希算法下是不可行的,即難題友好性。同時,哈希函數滿足高小熵分布,即變量均勻分布。
2. 橢圓曲線加密算法
橢圓曲線加密(Elliptic Curve Cryptography,ECC)算法是基于橢圓曲線數學的一種非對稱加密算法,其安全性依賴于橢圓曲線離線對數問題的困難性。比特幣系統的區塊鏈實現使用的橢圓曲線為secp256k1。
2.1 橢圓曲線的密碼學原理
橢圓曲線形如下圖所示,在橢圓曲線上,兩點相加得到的點依然在原橢圓曲線上,由此,在等式kP = P + P + …+ P = Q中,已知k和點P,求點Q比較容易,反之已知點Q和點P,求k卻是相當困難的。在實際應用中,k作為私有密鑰,而Q作為公開密鑰。
2.2 橢圓曲線密碼算法優點
橢圓曲線密碼算法有點有兩個,如下。同時,secp256k1橢圓曲線由于其構造的特殊性,其優化后的實現比其他曲線性能上可以提升30%。
- 短的密鑰長度,這意味著小的貸款和存儲要求;
- 所有的用戶可以選擇同一基域上的不同的橢圓曲線,可使所有的用戶使用同樣的操作完成域運算;
3. 零知識證明
3.1 什么是零知識證明
大多數的證明系統主要聚焦在系統本身的可靠性(Soundness)。原先大家都假設,在任何場景下證明者都可能是惡意的一方,并試圖誤導驗證者。但 Goldwasser 等人(幾個MIT的研究人員,牛逼啊)卻從另一個角度著眼,提出對于驗證者的道德質疑。他們的質疑是:我們如何知道在驗證過程中,驗證者不會泄露任何知識?以及在一次次驗證中,驗證者是否會從證明者手中從中獲得一定量的知識?(不得不佩服這個思考角度很輕奇)
舉個栗子:假設你想要使用密碼登錄網站,標準化的協議流程是這樣的:客戶端(你)寫下密碼并發送給服務器,服務器將你的密碼進行哈希運算,然后并對比存儲在服務器端的密碼哈希值。如果兩者相同,你便能登錄系統。上述過程中,服務器需要擁有你的密碼明文,所以你的隱私能否被保障就全看服務器端(也就是本場景下的驗證者)的臉色。如果服務器受到攻擊,甚至被入侵,那么你的密碼就會暴露給惡意攻擊者,導致嚴重的后果。為了應對這種問題,零知識證明在每個場景都有其創新性及必要性。
零知識證明核心是:證明者可以在不告訴驗證者某知識是什么的情況下,使得驗證者相信他們的確掌握該知識。
3.2 零知識證明的特性
零知識證明需要滿足以下特性:
- 完整性(Completeness):如果論述(校注:這里的“論述”即“零知識證明”中的“知識”)為真,那么誠實的證明者一定能說服誠實的驗證者。
- 可靠性(Soundness):如果證明者不誠實,他們無法通過造假來說服驗證者接受某論述。
- 零知識性(Zero-Knowledge):如果論述為真,驗證者無法得知論述實際內容是什么。
3.3 零知識證明舉例
你可能會想,你要向我證明你能解出某道題(擁有某種知識),又不告訴我答案,還要我相信你能解出這道題,這不是扯么?別慌,證明給你看。
我們用“尋找瓦爾多”游戲進行舉例說明,如下圖所示。這個游戲的玩法非常簡單,就是在圖中尋找一個瓦爾多這個人(眼睛有沒有看瞎?)。我們假設有兩個Anna(女)和 Carl(男)。Anna 告訴 Carl,她已經找到瓦爾多,但她不想告訴 Carl 瓦爾多的具體位置。現在,Anna 如何在不指出瓦爾多位置的情況下,向 Carl 證明她的確知道正確位置了?
這里有兩種證明方法:
- 中級證明方法:首先Anna把游戲圖片打印出來,然后背對著Carl扣出瓦爾多,然后給Carl展示瓦爾多,這里有一個問題就是如果事先Anna就有瓦爾多的圖片,那么Anna不用知道瓦爾多的位置也能騙過Carl,證明自己知道瓦爾多的位置。所以需要證明Anna手中的那個瓦爾多就是剛才從剛才打印出來的游戲圖片上扣出來的。很簡單,只需要事先在打印出來的圖片上做上某種無法篡改和編造的標記,這樣Anna扣出的瓦爾多后面的標記就能證明是不是打印圖片上的。
- 簡易證明方法:不需要打印,只需要找一張不透明的白紙(比游戲圖片大),然后Anna在這張白紙上扣一個小洞,然后用這張白紙覆蓋在游戲圖片上,并將扣出的小洞移動到瓦爾多的位置,這樣Carl可以看到瓦爾多真的被Anna找到了,但是由于整個游戲圖片被白紙擋著,所以Carl無法知道瓦爾多在游戲圖片中的具體位置。
4. 同態加密
4.1 什么是同態加密
我們都知道,在當下的互聯網環境下,數據是一個公司的基石,說是黃金一點不為過。但往往會發現出現一些尷尬的場景。比如,兩家公司在合作的過程中,A公司有技術,B公司有數據,A公司需要B公司的數據,B公司需要A公司的技術。但是對于B公司,一旦數據泄露就喪失了核心競爭力。面對這種情況,大部分合作到最后都是不歡而散。如何解決這個問題,同態加密或許能解決。
所謂同態加密(Homomorphic Encryption):允許對密文進行處理得到仍然是加密的結果。即對密文直接進行處理,跟對明文進行處理后再對處理結果加密,得到的結果相同。從抽象代數的角度講,保持了同態性。同態加密可以保證實現處理者無法訪問到數據自身的信息。
4.2 同態加密分類
根據同態加密函數的區別,我們可以將同態加密分成三類:
- 如果滿足 f(A)+f(B)=f(A+B) , 我們將這種加密函數叫做加法同態
- 如果滿足 f(A)×f(B)=f(A×B) ,我們將這種加密函數叫做乘法同態
如果一個加密函數f只滿足加法同態,就只能進行加減法運算;如果一個加密函數f只滿足乘法同態,就只能進行乘除法運算;如果一個加密函數同時滿足加法同態和乘法同態,稱為全同態加密。目前RSA 算法對于乘法操作是同態的;Paillier 算法則是對加法同態的;Gentry算法則是全同態的。
區塊鏈加密機制
1. 比特幣加密機制
比特幣以密碼學為支撐,構建了一個完備、安全、去中心化的數字貨幣體系,解決了數字資產所有權問題、雙重支付問題、現實世界的通貨膨脹問題甚至還預留了機制使得構建在資產轉移之上的智能合同成為可能,可以說比特幣就是一部加密機器,每個毛孔都滲透著密碼學的氣息。
1.1 比特幣地址
比特幣是一個交易機器(UTXO),交易依賴UTXO的地址,需要兼顧安全、效率和擴展。在比特幣中,地址是對公鑰的封裝,其生成過程如下圖所示:
tips:比特幣中采用橢圓曲線加密算法生成密鑰對,使用一個口令加密私鑰,并使用Base58Check對加密的私鑰進行編碼,保證了私鑰的存儲安全和傳輸安全。
需要注意的是比特幣地址對公鑰進行雙重HASH,為什么不用一重sha256算法?這是因為SHA1在2017年被攻破,采用的方法是birthday collision attack。社區覺得SHA2被攻破也是時間的問題,而抵御birthday collision attack的有效方法為雙重哈希算法。
1.2 數據存儲
比特幣的交易信息被包含在一個公開賬簿中,該賬簿是由一個個區塊連接而成,區塊由區塊頭和區塊體組成,區塊體中主要存儲交易信息(明文),區塊頭用于連接區塊,并形成一條鏈(區塊鏈)。區塊頭由三組區塊元數據組成。首先是一組引用父區塊哈希值的數據,這組元數據用于將該區塊與區塊鏈中前一區塊相連接;第二組元數據,即難度、時間戳和nonce,與挖礦競爭相關;第三組元數據是merkle樹根(一種用來有效地總結區塊中所有交易的數據結構),結構如下。在這里主要用到了HASH函數,一個是父區塊的HASH,用于連接連接前一個區塊,還有一個地方就是Merkle Tree,其中也是通過Hash的方式。
這種數據結構有效的避免了雙重支付問題,因為攻擊者沒有辦法對這筆支付之前的所有消息進行檢索直至追溯到原始的挖礦區塊,實際上比特幣世界里的每一枚比特幣都是被標記可溯源。
1.3 Merkle Tree
之所以把MT(Merkle Tree)單獨拿出來說,是因為這個數據結構實在太重要了,為啥重要呢?1)確保交易的完整性;2)防篡改;3)歷史留痕可追溯。尤其是在確保交易的完整性方面,MT大大減少了數據的傳輸量和計算的復雜度,時間復雜度為O(1)。
MT是一種樹、具有樹的所有特點,MT的葉子節點存儲具體的交易,非葉子節點根據下面的所有節點值,按照逐層HASH的方式求得,結構如下圖所示:
1.4 交易過程
比特幣中僅僅支持交易的UTXO,可以把一筆交易理解為匯款。如下圖所示Owner0給Owner1匯款。匯款過程為:
- Owner0 先查到 Owner1 的公鑰。用 Owner1 的公鑰(Public Key)把匯款詳情加密。這樣,只有 Owner1 本人用自己的私鑰(Private Key),才能打開加了密的匯款詳情;
- 為了方便 Owner1 驗證這筆匯款的確來自 Owner0,而不是別人,Owner0 發出的匯款單里,除了有加了密的匯款詳情,還有 Owner0 的數字簽(Signature)。Owner1 拿到匯款時,為了驗證這筆匯款的確來自 Owner0,他可以用 Owner0 的公鑰,來驗證匯款單中 Owner0 的數字簽名;
- Owner0 發出匯款單時,匯款單不僅僅投遞到 Owner1,而且還要廣而告之,任何人只要愿意參與 BitCoin 審計,都可以收到全球所有人發出的所有匯款單;
- 沿用 1、2、3 的原理,Owner1 給 Owner2 匯款,然后 Owner2 給 Owner3 匯款。BitCoin 通過 Hash 機制,把涉及同一枚 BitCoin 的所有匯款交易(Tranaction)串連起來,目的是為了追查重復付款(double spending)的欺詐行為;
1.5 挖礦原理
挖礦實際上是挖礦節點爭奪記賬權。主要的過程為通過不斷的調整nonce值去計算一個雙重SHA256,然后和區塊target值比較,如果小于target,則成功。可以知道挖礦的本質實際上是不斷的調整nonce值進行雙重SHA256計算,如下:
SHA256(SHA256(version , prev_hash , root_hash , time , difficulty, nonce))
其中,version為區塊版本號;prev_hash為上一個區塊的hash值;root_hash為MT的根哈希;time為時間戳;difficulty為全網當前難度;nonce就是需要調整的隨機數。
2. 以太坊加密機制
以太坊和比特幣最大的區別在于支持上層的智能合約,使得區塊鏈不僅能完成基于UTXO的轉賬交易,還可以做任何計算機語言可以做的事情,即具備圖靈完備性。以太坊的公私鑰和比特幣一樣采用的是secp256k1橢圓曲線加密算法生成,同時以太坊的共識機制也是POW,即挖礦原理和比特幣是一樣的。
2.1 以太坊公私鑰和地址
以太坊的地址和比特幣地址不同的是,以太坊地址代表的是一個以太坊賬戶。以太坊的賬戶分為兩種,一種是外部賬戶,存儲賬戶余額,用戶進行轉賬交易;一種是合約賬戶,用戶存儲合約數據,用于對合約的操作。每一個賬戶都有一個私鑰和公鑰,賬戶地址由公鑰生成,去公鑰的最后20個字節。
在以太坊中,采用橢圓曲線加密算法secp256k1生成密鑰對。私鑰保存在keystore文件中,為了確保私鑰沒有在文件中明文存儲,以太坊采用對稱加密算法cipher對私鑰進行加密(aes-128-ctr 加密模式),同時支持自定義密碼保護,不需要記住解密密文。過程如下圖所示:
大致過程為,首先你需要輸入你自己的密碼,然后以太坊用一個密鑰生成函數(kdf)計算解密密鑰,然后將解密密鑰和ciphertext密文鏈接并進行處理,然后和mac比較確保密碼正確,最后通過cpher對稱函數用解密密鑰對ciphertext密文解密,最后就得到了私鑰。
有了公鑰和私鑰,我們看一下以太坊的賬戶地址是如何生成的?非常簡單。以太坊公鑰是一個以04開通的64位的字符串,首先去掉04,然后進行keccak-256哈希,得到長度為64的16進制字符串,去掉開頭的24為,并在前面加上“0x”,即為以太坊地址。
2.2 數據存儲
以太坊為了能夠快速回溯,將每一次交易的數據通過MPT進行組織,并以并以[key, value]的形式持久化在內置的LevelDB中。在以太坊中需要存儲的數據包括合約和賬戶的狀態、交易信息及交易回執。以太坊區塊不同于比特幣區塊的地方在于用三個MPT(Merkle Patricia Tree)維護交易和合約狀態。其中MPT是一種經過改良的、融合了默克爾樹和前綴樹兩種樹結構優點的數據結構。這三個MPT分別為StateDB、Transactions、Receipts。以太坊中MPT的結構如下:
以太坊的MPT是對patricia tree 前綴樹的改良,具體表現在:
- 傳統的PT的高度不可控,如果出現一個字符串沒有公共前綴,會出現一顆極其不平衡的樹,從而拖慢整棵樹的性能。以太坊通過設置葉子節點和擴展進店對傳統PT的對路徑進行了壓縮,確保了樹的高度平緩。
- 安全系數不高。原PT的節點value以明文存儲內容,而以太坊改良后通過RLP編碼存儲,并且存儲的是[key, value]的形式,其中key是PRL編碼的hash值,指針不直接指向內存地址,同樣為hash值。
2.3 交易簽名
這里不對具體的交易過程進行描述,只說明數字簽名過程和校驗簽名過程。
對于簽名,其實就是用私鑰對消息的哈希進行加密。當一個以太坊節點向另一個節點發送消息時,會用自己的私鑰將消息的哈希做簽名,然后吧簽名和消息本身發送給對方,如下圖所示:
節點收到對方發來的消息和簽名后,會先做一個“recover”的動作,用消息和簽名推導出對方的公鑰。再通過公鑰,簽名,消息的哈希值計算出一個叫“r”的值,這個r是簽名的一部分,校驗簽名就是拿計算出來的r和簽名中攜帶的r經行對比,如果一致就校驗通過,如下圖所示:
寫在最后
最近針對區塊鏈的加密機制進行了梳理,相關內容沒有什么新的東西,而且也不一定比網上的一些資料全面。但對于自身而言,根據自己的理解和自己的語言去總結,是一個不斷學習和鞏固的過程,而且這種方式的印象更深刻。密碼學在區塊鏈中扮演著重要的角色,通過各種巧妙的方式,使得區塊鏈上的數據保持了匿名性、唯一性、完整性和安全性。當然密碼學目前還是有不少挑戰,基于上述加密方式的區塊鏈解決方案也存在諸多問題,比如MPT樹的擴容問題。還是那句話,革命尚未成功,同志仍需努力,密碼學也一樣。
【參考文獻】
- 漫談系列:聊聊區塊鏈數據的“安全”和“控制權”
- 零知識證明:一對一匿名可監管轉賬的用戶端和監管端
- 群簽名&&環簽名客戶端
- 群簽名&&環簽名RPC服務
- 加密經濟的信任引擎
- 數字簽名、數字證書、SSL、https是什么關系
- 加密經濟學應用的機制設計
- 零知識證明:拋磚引玉
- 什么是zkSNARKs:謎一般的“月亮數學”加密,Part-1
- 什么是zkSNARKs:謎一般的“月亮數學”加密,Part-2
- 什么是以太坊私鑰儲存(Keystore)文件
- 怎么在區塊鏈上保護隱私
- 關于錢包的基礎密碼學
- Merkle Patricia Tree詳解
- 能夠證明你是你的數字簽名和多重簽名
- 我國SM2與SM9數字簽名標準證書成為國際標準
- Google震驚密碼界:攻破了最流行的SH-1算法
- [以太坊源代碼分析] IV. 橢圓曲線密碼學和以太坊中的橢圓曲線數字簽名算法應用
- 加密解密、數字簽名及證書
- 比特幣背后的密碼學原理
- Ethereum基礎】:賬戶、地址、私鑰和公鑰
- 區塊鏈技術指南
- 區塊鏈開發實戰