橢圓曲線數字簽名應用原理
- 收發檔案場景下的數字簽名
- 位元幣區塊鏈場景下的數字簽名
本文旨在理解橢圓曲線數字簽名的程序,不涉及數學推導與過多專業術語,如想了解橢圓曲線數字簽名的底層數學原理,請參考libsecp256k1位元幣密碼演算法開源庫(五)中公鑰生成、簽名和簽名驗證中的相關內容,
收發檔案場景下的數字簽名
在開始前定義幾個量:檔案的發送方A、檔案的接收方B、企圖竊密或篡改檔案的第三方C,可以想象一個場景,某天B收到了一個檔案,這個檔案說是A發來的,但是B不知道這個檔案是不是A發來的,如果是A發來的,B也不知道檔案的內容是否被篡改過了,數字簽名就可以給B解決這兩個問題,
在回答這個問題前,先說B收到了A發來的檔案,要保證這個檔案不會被C知道是什么意思,首先需要對這個檔案加密,
在非對稱加密體系中,要用公鑰加密私鑰解密,
下面具體解釋一下私鑰和公鑰:首先每個人都有自己的公鑰和私鑰對,就是說A有他的公鑰a和私鑰a,B也有他的公鑰b和私鑰b,私鑰是在本地產生的,也就是說某天A想,他也許該有個私鑰了,于是他就自己想了一串數當做自己的私鑰a,這個私鑰就他自己知道,不能告訴別人(不然就不是本地了),但是他的公鑰會是什么樣子呢,他也不知道,他將自己想出來的私鑰a放到橢圓曲線方程中,生成了他的公鑰a(私鑰生成公鑰的具體數學程序可以看我之前的博客,但這里不會影響理解),這個公鑰很復雜,A可以把他的私鑰放到橢圓曲線里面得到他的公鑰,但把他的公鑰放到橢圓曲線里面卻無論如何得不到他的私鑰,A可以將他的公鑰告訴任何人,當然也可以告訴給竊密者C,B產生公鑰b和私鑰b的程序也一樣,
某天A想給B發訊息了,于是A找到了B的公鑰(前面說過公鑰是完全公開的),A用B的公鑰b對自己要發送的檔案加密——這樣C就完全不知道這個檔案內容是什么了——然后將加密的結果發給了B,B得到這個檔案后用自己的私鑰b就可以對檔案解密,看到檔案的內容了,
這個程序當然存在一些問題,B解開這個檔案一看開頭一個Dear B結尾一個Yours A,檔案看樣子是A發來的,但有沒有可能是C假冒A發給B的呢?如果是A發來的,那么檔案的內容是否被偷偷篡改過了?解決這兩個問題就需要數字簽名,
那么數字簽名是如何實作的呢,要用私鑰簽名公鑰驗證,
先說數字簽名是怎么得來的:首先A會對自己要發送的檔案進行hash運算,hash運算結果稱之為這個檔案的hash摘要,hash函式有幾個性質:hash會讓這個檔案變成很短的一個位元串(具體多短要看使用的hash函式),即便是A給B發了一本莎士比亞歌劇最后hash得到的hash摘要也會是很短的位元串;用同一個hash函式哈希結果不同,但長度一定是一樣的,用同一個hash函式對莎士比亞格局的hash結果和一個字母的hash結果是等長的位元串;根據hash摘要無論如何也無法推斷或還原成為最初的源檔案;hash具有雪崩的特點,即改變hash前的檔案哪怕一個標點,得到的hash結果也會完全不同,同樣如果源檔案沒有改變,hash結果也不會改變,hash結束得到檔案的hash摘要,A的私鑰a和A隨機產生的亂數k(k究竟是什么參見我之前的博客,但這里不會影響理解)經過一系列運算會得到A的數字簽名 sign a,
然后說加入數字簽名后發送檔案的程序:A會將他的數字簽名sign a,他的公鑰a附帶上他的被B的公鑰b加密的檔案一起發送給B,B收到之后會先用自己的私鑰b對檔案進行解密,得到這個檔案,再對收到的這個檔案進行hash運算,然后B會用這個檔案的hash摘要、A的公鑰a來對這個數字簽名sign a進行驗證,如果驗證通過了,就既說明這個檔案在傳輸程序中沒有被惡意篡改,又說明這個檔案也確實是A發來的,
位元幣區塊鏈場景下的數字簽名
在開始前定義幾個量:一筆交易 β \beta β的發起方P、交易的接收方A,即A收到了P轉來的錢,隨即A用從P得到的錢發起另一筆交易 α \alpha α,交易 α \alpha α的發起方A、交易的接收方B,即A把從P那里得到的錢轉給了B,在本例中重點分析A向B轉賬的交易 α \alpha α,
在正常生活中轉賬一般要通過銀行機構,A給B轉賬時首先A會到銀行去,提交要轉賬的資訊,銀行就會看A賬戶里面余額是不是夠給B轉賬,如果夠就把A賬戶中的相應金額轉給B,
但在位元幣區塊鏈場景下,情況會有些不同,區塊鏈是一個去中心化的系統,不存在“銀行”的概念,A給B轉賬時,A有沒有錢自然也不會由一個中心化的系統(即銀行)來核驗,而是由非常多的網路節點來核驗,
這里我們直接假設網路中的節點大部分都是好節點,如果一個交易是正確的,好節點就會把這個正確的交易寫入到自己的區塊里,然后這個節點會通過“挖礦”讓自己的區塊成為一個合法區塊,并告訴其他節點自己的合法區塊,其他節點經過驗證,發現這個區塊里面的交易都是正確的,而且這個區塊本身也是合法的,就會接納這個區塊,當這個區塊真正被接納后,這個交易也就不可被篡改,A給B轉賬這件事也就坐實了,在這個程序中就算有一些作惡的壞節點就是認為一個正確的交易是錯誤的,始終不把一個正確的交易給裝到自己的區塊里面,也會有大部分的好節點愿意把這個交易裝到自己的區塊里面,
那么節點們核驗一個交易是不是正確的標準是什么呢?試想一個A與B交易的場景:某天B收到了來自A的一筆錢,那么這筆錢究竟是不是A本人同意轉出的錢呢,畢竟也有可能是B偷用A的錢轉給了自己;如果真的是A把這筆錢轉給了B,B是否真的就得到這筆錢了,也就是說A可能沒有錢,A給B轉的錢就是一張“空頭支票”,
所以,節點們核驗一個交易是不是正確就看兩點:第一,錢是A本人轉給的B,不是有人偷用A的錢轉給B;第二,A確實有錢可以轉給B,
想要核驗這兩點,需要理解在一筆交易中有兩個重要的概念,那就是輸入和輸出,在一筆交易中可能有多個輸入,也可能會有多個輸出,這其實很容易理解,一個人轉給另一個人的錢可能來自很多個人,同時一個人也可能把一筆錢轉給了很多個人,但這里為了方便理解,交易
β
\beta
β只包含P給A轉錢,對應的后續交易
α
\alpha
α也只包含A給B轉錢,交易
β
\beta
β中有一對輸入和輸出,交易
α
\alpha
α中也有一對輸入和輸出,
在交易
α
\alpha
α的輸入中,A給出了自己的數字簽名sign a和公鑰a,在交易
α
\alpha
α的輸出中,A給出了轉賬接收方B的公鑰b的hash值,即
h
a
s
h
(
公
鑰
b
)
hash(公鑰b)
hash(公鑰b);同樣的,在交易
β
\beta
β的輸入中,P給出了自己的數字簽名sign p和公鑰p,在交易
β
\beta
β的輸出中,P給出了轉賬接收方A的公鑰a的hash值,
這里我們只看A給B轉賬的交易
α
\alpha
α,那么其實想要核驗一個交易是不是正確就很簡單了:第一,核驗錢是不是真的由A轉出,只需在交易
α
\alpha
α的輸入中,用A的公鑰a驗證數字簽名sign a是否正確,如果驗證正確,那么這筆錢確實是由A轉出的;第二,核驗A是否真的有錢轉給B,只需將交易
α
\alpha
α的輸入中A的公鑰a求hash值,與交易
β
\beta
β的輸出中的A的公鑰a的hash值比對,如果一樣,就說明A確實有一筆來自P的轉賬,也就說明A真的有錢轉給B,
同樣地,B也可以使用這樣的方式將來自A的錢轉給其他人,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/332158.html
標籤:區塊鏈
