數字簽名簡介

原文鏈接:https://blog.csdn.net/qq_39832544/article/details/79345878

序言


簽名的作用無非就是證明某個文件上的內容確實是我寫的/我認同的,別人不能冒充我的簽名(不可僞造),我也不能否認上面的簽名是我的(不可抵賴)。

我們知道,手寫簽名之所以不能僞造,是因爲每一個人的筆跡都是獨一無二的,即使模仿,也可以通過專家鑑定分別出來。而不可抵賴,是因爲每個人的筆跡都有固定特徵,這些特徵是很難擺脫的。

正是這兩點特性使得手寫簽名在日常生活中被廣泛承認,比如籤合同、借條等等。

而數字簽名,它的作用跟手寫簽名其實是一樣的,用來證明某個消息或者文件是本人發出/認同的。我國在2005年就已經施行《電子簽名法》,確立了電子簽名(包括但不限於數字簽名)的法律效力。

那麼數字簽名又是靠什麼保證不可僞造和不可抵賴兩個特性呢?

答案是利用公鑰加密系統。常用的簽名算法有

  • RSA,基於大整數分解問題
  • DSA,基於離散對數問題
  • ECDSA,屬於DSA的一個變種,基於橢圓曲線上的離散對數問題

其中RSA是實現數字簽名最簡單的公鑰加密方法。

RSA簽名


RSA是一個非常神奇的加密算法,它具有一個離散對數和橢圓曲線加密都沒有的特性:

既可以用公鑰加密然後私鑰解密,也可以用私鑰加密然後公鑰解密(對稱性)。

公鑰加密然後私鑰解密,可以用於通信中擁有公鑰的一方向擁有私鑰的另一方傳遞機密信息,不被第三方竊聽。
那麼私鑰加密然後公鑰解密是用在什麼場合呢?就是數字簽名。

因爲RSA中的每一個公鑰都有唯一的私鑰與之對應,任一公鑰只能解開對應私鑰加密的內容。換句話說,其它私鑰加密的內容,這個公鑰是解不開的。

這樣,如果你生成了一對RSA密鑰,你把公鑰公佈出去,並告訴全世界人這個公鑰是你的。之後你只要在發送的消息,比如“123456”,後面加上用私鑰加密過的密文,其他人拿公鑰解密,看解密得到的內容是不是“123456”就可以知道這個“123456”是不是你發的。

其他人因爲沒有對應的私鑰,所以沒法生成公鑰可以解密的密文,所以是不可僞造的。
又因爲公鑰對應的私鑰只有一個,所以只要能成功解密,那麼發消息的一定是你,不會是其他人,所以是不可抵賴的。

當然,在數字簽名的過程中,我們不需要對“123456”保密,所以加密、解密這樣的名詞在這個場景中並不準確,用簽名解籤會更合適。

實際應用中,由於直接對原消息進行簽名有安全性問題,而且原消息往往比較大,直接使用RSA算法進行簽名速度會比較慢,所以我們一般對消息計算其摘要(使用SHA-256等安全的摘要算法),然後對摘要進行簽名。只要使用的摘要算法是安全的(MD5、SHA-1已經不安全了),那麼這種方式的數字簽名就是安全的。

一個具體的RSA簽名過程如下:

  1. 小明對外發布公鑰,並聲明對應的私鑰在自己手上
  2. 小明對消息M計算摘要,得到摘要D
  3. 小明使用私鑰對D進行簽名,得到簽名S
  4. 將M和S一起發送出去

驗證過程如下:

  1. 接收者首先對M使用跟小明一樣的摘要算法計算摘要,得到D
  2. 使用小明公鑰對S進行解籤,得到D’
  3. 如果D和D’相同,那麼證明M確實是小明發出的,並且沒有被篡改過

應用


手寫簽名可以用來籤合同,那麼數字簽名可以用來幹什麼呢?

網站認證

首先最常見的用處就是用來認證一個網站的身份。
比如我打開百度,百度是怎麼保證顯示在我眼前的網頁就一定是百度生成的,不是其他人修改的呢?就是藉助數字簽名來實現的。

用IE瀏覽器打開百度,點擊地址欄旁邊的小鎖,再點擊查看證書,就可以看到百度主頁的數字簽名證書了。所謂證書,其實是對公鑰的封裝,在公鑰的基礎上添加了諸如頒發者之類的信息。
這裏寫圖片描述

“簽名算法”一欄可以看到,它使用的是sha256RSA,也就是使用SHA-256計算摘要,然後使用RSA對摘要進行簽名。而在“公鑰”一欄則保存着該證書的“本體”,用於驗證簽名的RSA公鑰。

代碼簽名

而除此之外,還有個地方我們經常碰到數字簽名的——代碼簽名。

如果Windows上的可執行程序程序來源於正規公司,那麼通常它會有代碼簽名,用於確保其來源可靠且未被篡改。以QQ爲例,它的數字簽名是這樣的。
代碼簽名

如果某個程序沒有數字簽名,那麼它的安全性往往就沒有保證,如果它有數字簽名,但是顯示“此數字前面無效”,那麼這個程序要麼被篡改了要麼損壞了,不管哪種可能都不應該嘗試執行它。

實際上,驗證數字簽名並不需要我們手動去查看,如果你沒有關閉Windows的UAC(用戶賬戶控制)功能,那麼你在執行任何程序的時候系統都會自動驗證其簽名,如果是簽名有效的程序,那麼彈出來的UAC對話框是藍色或者灰色的,如果沒有簽名,那麼會是醒目黃色的。而如果簽名被阻止,則會顯示紅色並且不允許執行。

但是數字簽名不是萬能的。事實上不管是瀏覽器的數字簽名還是代碼的數字簽名,都依賴於系統或者瀏覽器內置的根證書,如果電腦本身已經中毒或者被入侵,那麼這些根證書可以被輕易添加或者修改,這時的數字簽名的安全性可以說是蕩然無存了。

即使是正常簽名的軟件,也不能保證發行公司不耍流氓,很多流氓軟件都是由一些不知名的小公司搞出來的;或者某些小公司篡改知名軟件,加入自己的代碼,然後用自己的私鑰進行簽名,這些數字簽名也都是有效的,但是我相信你不會想運行這些軟件的。如果對安全性要求比較高,可以手動或者藉助工具吊銷那些不太安全的根證書,具體方法已經超出本文討論範疇,讀者可以自行尋找。

比特幣

比特幣是一種完全匿名的數字貨幣,它的身份認證是基於ECDSA。比特幣的賬戶地址就是對公鑰計算摘要得到的,向全世界公佈。而確認你是賬戶擁有者的唯一辦法就是看你有沒有賬戶對應的私鑰。對於比特幣中的任意一個交易記錄,只有當其中付款方的簽名是有效的,它纔是有效的。如果賬戶私鑰丟失,那麼你將永遠地失去裏面的錢;一旦被黑客盜取,裏面的錢就完全歸黑客所有。

DSA


上面說到,RSA是數字簽名最簡單的算法,爲了做對比,大家可以感受一下DSA是如何實現的。

  • 參數生成:

    1. 選取素數q
    2. 選取素數p使得p-1是q的整數倍
    3. 隨機選取小於p-1的整數h,計算
    4. 選取小於q的正整數x作爲私鑰
    5. 計算 得到公鑰
  • 簽名(其中H(M)是消息M的摘要):

    1. 對每一條消息隨機生成大於1小於q的整數k
    2. 計算,如果r=0,重新回到步驟1
    3. 計算,如果s=0,重新回到步驟1
    4. 得到簽名(r, s)
  • 驗證:

    1. 計算
    2. 計算
    3. 計算
    4. 計算
    5. 如果v=r,則簽名有效,否則無效

可以看到DSA過程明顯要比RSA簽名複雜不少,除非親自動手去推導它的正確性,不然很難直觀地感受爲什麼這樣是可行的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章