作者:Zarten

知乎專欄:區塊鏈技術詳解

知乎ID:Zarten

簡介: 網際網路一線工作者,尊重原創並歡迎評論留言指出不足之處,也希望多些關注和點贊是給作者最好的鼓勵 !

概述

比特幣其實是一種加密貨幣(Encryption currency),加密部分內部是利用密碼學原理,主要用到密碼學中的2個功能:雜湊和簽名。

雜湊

雜湊函式又稱為雜湊函式,是一種從任何一種資料中建立小的數字“指紋”的方法。雜湊函式把訊息或資料壓縮成摘要,使得資料量變小,將資料的格式固定下來。

雜湊函式有3個重要的性質,這些性質是比特幣的基礎,也為比特幣提供了安全保障,分別為:

1。抗碰撞性(collision resistance)。collision:碰撞 resistance:抵抗

2。隱蔽性(hiding)

3。謎題友好性(puzzle friendly)。puzzle:迷惑,謎題

下面詳細講解這3個性質。

1.抗碰撞性(collision resistance)

碰撞性是指雜湊碰撞,雜湊碰撞的產生:給定輸入的2個值x和y,若經過雜湊函式運算,使得輸出H(x)=H(y),此時就產生了雜湊碰撞。

雜湊碰撞是很常見的,此時不同的輸入會對映到雜湊表中的同一個位置,畢竟輸入是無窮大的,而輸出只是在有限的雜湊表中,比如比特幣中的雜湊函式SHA-256,有2的256次方空間容納,儘管這個數字相當巨大,但還是比輸入(無窮大)小,所以說雜湊碰撞是不可避免的。

而現在所說的抗碰撞性是指:雖然說會產生雜湊碰撞,但這種雜湊碰撞很難被人為製造,也就是給定一個輸入m,雜湊運算得到H(m),但是很難人工找到另外一個輸入m‘,使得2次的雜湊結果完全相同,即H(m)=H(m’)。

透過上面充分理解抗碰撞性後,得到一個應用,比如防篡改性應用。比如你有一份重要檔案,需要上傳在雲伺服器上,上傳前對這份檔案進行雜湊運算並儲存結果在本地,過一段時間下載時,為了判斷這份檔案是否篡改過,只需再一次對這份檔案雜湊運算,跟上傳前的雜湊值比較,若相等,則沒有篡改,否則篡改過。因為篡改者很難人為的製造篡改後的雜湊值跟篡改前的一模一樣。

這裡有一個例外是MD5演算法,以前很流行的雜湊函式,但是經過實踐經驗現在已經知道如何去製造MD5的雜湊碰撞。比特幣中使用的雜湊函式為SHA-256,目前還沒有找到雜湊碰撞的方法。

2.隱蔽性(hiding)

隱蔽性也就是雜湊函式是單向不可逆性,也就是說一個輸入x,可以計算雜湊值為H(x),但透過H(x),不能反向計算出這個x,除非暴力破解,也就是一個個去試。所以這個隱蔽性的前提是輸入的空間要足夠大且輸入的取值要分佈均勻,若輸入的空間已經足夠大了,但所有取值只在一小塊區間中,這樣也是不行的。

3.謎題友好性(puzzle friendly)

所謂謎題友好性是指,計算的雜湊值結果是不可預測的,比如某個輸入x,想要雜湊值H(x)在某個範圍內,沒有什麼捷徑可走,只能一個個去嘗試這個x。

這個性質在區塊鏈中有個重要的例子,就是比特幣挖礦,也是比特幣挖礦的本質。

在比特幣的區塊鏈中,每個區塊有一個區塊頭,區塊頭中其中的2個域,分別為隨機數nonce和目標值target。

礦工們要做的事情就是不斷的嘗試這個nonce值,並將這個nonce值結合區塊頭資訊一起作為輸入,然後計算雜湊值。若雜湊值小於或等於這個target值,說明挖礦成功,否則不成功,繼續嘗試其他nonce值。

H(block header + nonce) <=target

透過上面可知,要想取得某個nonce值滿足上面公式,沒有什麼捷徑可走,只能一個個去嘗試,所以只能做大量的工作來驗證,這就是所謂的工作量證明POW(proof of work),也就是所謂的比特幣挖礦。

雖然說挖礦的過程很難,但若挖礦成功後其他礦工驗證其結果很簡單,只需計算一次,看是否滿足要求即可。

簽名

簽名使用的是非對稱加密方式 ,為了能更好的理解這種加密方式的好處,我們先來簡單說下對稱加密方式。

對稱加密方式中,秘鑰只有一個,通訊雙方都使用這個秘鑰進行加密和解密,此時通訊內容在網路中以密文方式進行傳輸,也非常安全,但有個問題是,在網路中如何將這個秘鑰傳送給對方是個棘手的問題,不可能以明文傳輸吧,所以說還是不安全的。

非對稱加密方式就很好的解決了上面的問題。

在非對稱加密中,有一個成對的秘鑰,分別為公鑰(public key)和私鑰(private key),公鑰是公開的,私鑰只有自己知道。其中公鑰和私鑰都用來相互的加密和解密,1。公鑰加密,私鑰解密;2。私鑰加密,公鑰解密。

上面2點對應非對稱加密方式中的2個應用,加密和簽名。

1.加密:公鑰加密,私鑰解密。

2.簽名:私鑰加密,公鑰解密。

1.加密

這種加密方式是區別於對稱加密方式,不需要在網路中傳遞秘鑰,造成風險。

由於通訊雙方中的公鑰都是公開的,一方在傳遞資訊時只需用對方的公鑰加密即可,對方收到訊息後用自己的私鑰解密。

2.簽名

簽名(Signature)也就是數字簽名(digital signature)

簽名(Signature)的含義就是讓別人相信:某個內容確實是你發出去的,而不是別人偽造的,且傳送內容是被你認可的(沒有被篡改過)。傳送方在傳送內容時用自己的私鑰給內容加密,由於公鑰都是公開的,且只有對應的公鑰才能解密,接收方可以用傳送方的公鑰解密來驗證是否合法。

簽名後為什麼別人無法偽造呢?只需解決以下2個問題即可:

1.訊息確實是你發出的。

2.訊息沒有被篡改過。

舉個例子,zarten1簽名傳送後,zarten2驗證,簽名的過程如下:

zarten1簽名的過程分為3部分:

1。訊息經過雜湊運算生成摘要(digest)。

2。用自己的私鑰對摘要加密。

3。zarten1將訊息(包括公鑰)和加密後的摘要一起傳送出去。

zarten2驗證的過程也分為2部分:

1。用zarten1的公鑰解密之前加密後的摘要。

2。用zarten1相同的雜湊函式計算訊息內容。

對於第1點,可以驗證“訊息確實是你發出的”,zarten2用zarten1的公鑰解密之前加密過的摘要,若能正確解密出摘要,則證明“訊息確實是你發出的”。因為公私鑰是成對出現的,冒充者不知道你的私鑰,跟zarten1公開的公鑰不成對,所以也就解不開。

對於第2點,可以驗證“訊息沒有被篡改過”,根據前面部分講解的雜湊的特徵之一:抗碰撞性(collision resistance),zarten2對訊息進行雜湊運算,若計算出的摘要和剛剛解密出來的摘要相等,則證明“訊息沒有被篡改過”。

比特幣賬戶

比特幣賬戶實際上就是一個公私鑰對,可以非常方便的用來簽名。

在比特幣中產生一個賬戶只需自己生成一對公鑰和私鑰,公鑰可以公開,私鑰需要自己儲存且不能洩露,一旦洩露則意味著你的比特幣賬戶已經洩露。這個公私鑰對主要用來簽名,比如zarten1轉賬5個BTC給zarten2,zarten1需要用私鑰進行簽名,讓區塊鏈全節點知道確實是zarten1轉賬給了zarten2,且別人也無法冒名轉走你賬戶的比特幣,因為不知道你的私鑰。

若某個人想轉走你的比特幣,因為不知道你的私鑰,所以他就在本地大量的生成公私鑰對,看生成公鑰是否跟你的公鑰相等,若相等則私鑰也相等,這樣就可以輕而易舉的獲取你的賬戶,理論上好像是可行的,而實際上是不可行的,若是256位雜湊值,產生跟別人相同的公私鑰對的機率是非常小的(估計比地球爆炸的機率還小)

生成比特幣賬戶是隨機的,為了防止比特幣中賬戶的碰撞,在生成賬戶(公私鑰對)時要有好的隨機源。