文章目錄
-
- 直接對消息進行簽名
- 對消息的hash值進行簽名
- 我們需要數字簽名
- 簽名的生成和驗證
- 數字簽名的方法
- 數字簽名可以替代現實生活中的簽名嗎?
- 數字簽名無法解決的問題
之前的文章我們講了MAC(Message Authentication Code)消息認證碼,MAC是認證消息的完整性的技術。它是由任意長度的消息和在發送者和接受者中間共享的密鑰生成的。
MAC有個缺點就是秘鑰是共享的,因為是共享的是以發送者可以計算MAC值,接收者也可以計算出同樣的MAC值。因為兩者都可以計算出同樣的MAC值,是以我們無法判斷這個MAC值到底是由誰來計算出來的。這裡提到了MAC的缺點就是無法防止否認。
如果發送者A和接收者B使用不同的密鑰,例如A發送消息的時候使用私鑰對消息進行加密,B接收消息的時候使用公鑰對消息進行解密。因為消息隻能由A的私鑰進行加密,是以這個簽名一定是由A簽發的,這樣就沒有否認的問題了。這個就是數字簽名(digital signature)。
生成消息簽名這一行為是由發送者A來完成的,也稱為對消息進行簽名。生成簽名就是根據消息内容計算簽名值,生成簽名意味着A認可這個消息的内容。
驗證數字簽名可以由消息接受者B來完成,也可以由第三方來完成。驗證成功意味着這個消息是由A發出,失敗則表示這個消息不是A發出的。
在數字簽名的過程中,消息發送者A和消息接受者B使用不同的密鑰來進行簽名和驗證。這裡使用的不同的密鑰就是公鑰和私鑰。
數字簽名其實就是公鑰密碼的反向應用,下面我們看看兩種的不同:
名稱 | 私鑰 | 公鑰 |
---|---|---|
公鑰密碼 | 接受者解密時使用 | 發送者加密時使用 |
數字簽名 | 簽名者生成簽名時使用 | 驗證者驗證簽名時使用 |
誰持有密鑰? | 個人持有 | 主要需要,任何人都可以持有 |
通常來說數字簽名一般有兩種方式:
下面我們分别來介紹兩種方式。
直接對消息簽名包含如下幾個步驟:
- 發送者A用自己的私鑰對消息進行加密生成簽名。
- A将加密後的簽名和消息發送給B。
- B用A的公鑰對消息簽名進行解密,進而得到簽名之前的消息M1。
- B将M1和A直接發送過來的消息M2進行對比,兩者一緻則簽名成功,否則失敗。
這裡我們注意一下第四個步驟,簽名的目的是保證消息是由隻持有該密鑰的人生成的,而并不是要保證消息傳遞的機密性。也就是說數字簽名本身并不是用來保證機密性的。如果要保證機密性則可以将消息加密之後再發出去。
上面的直接對消息進行簽名,看起來非常簡單,但是在實際應用中很少用到。因為要對整個消息進行簽名時一個非常耗時的操作,是以通常我們會使用單向散列函數對消息進行處理得出一個hash值,然後對這個hash值進行簽名:
- A用單向散列函數對消息進行計算hash值。
- A用自己的私鑰對hash值進行簽名。
- A将消息和簽名發給B
- B用A的公鑰對簽名進行解密得到hash值。
- B使用單向散列函數對消息進行計算,将結果和4進行比對。
我們講解了怎麼實作數字簽名,我們也可能聽說在現實生活中有電子簽名這個東西。
數字簽名有很多技術上的優點,不需要實體互動就可以簽訂合同,并可以對任何資料進行簽名。那麼在實際上數字簽名能不能替代實際簽名的問題是一個複雜的社會行為。
因為我們在使用電子簽的時候,沒有人會親自去設計簽名算法,而是簡單的根據軟體提供的資訊按下簽名按鈕。
那麼這個簽名軟體是否值得信任,就是我們需要關注的問題。
使用數字簽名我們可以防止僞造和篡改,也無法防止否認。但是還需要一個大前提就是驗證簽名的公鑰必須是真正屬于發送者。
- 區塊鍊從入門到放棄系列教程-涵蓋密碼學,超級賬本,以太坊,Libra,比特币等持續更新
- Spring Boot 2.X系列教程:七天從無到有掌握Spring Boot-持續更新
- Spring 5.X系列教程:滿足你對Spring5的一切想象-持續更新
- java程式員從小工到專家成神之路(2020版)-持續更新中,附詳細文章教程