透過 Nodejs crypto 幫訊息簽名(Sign)並驗證(Verify)

如何驗證收到的非對稱加密訊息內容(明文)後,為原始的內容而非竄改過後呢?

Whien
4 min readOct 31, 2019
完整流程圖

〉前情提要

在上篇「透過 Nodejs crypto 幫助男孩與女孩完成非對稱加密的私訊傳輸」中提到,最後男孩順利的將訊息如期發送給女孩,並且沒有任何人能夠偷看彼此的訊息。

〉下一個問題

雖然訊息到了,但女孩是不是有辦法可以確認「收到的訊息內容」是否與男孩所「發送的訊息內容」一致呢?

》現在面臨的問題,到底訊息是不是對的?

現在女孩收到了,但因為訊息是從遠方而來,她想更近一步知道這訊息是否跟男孩所發送的內容一模一樣而沒有被偷改過。

{
"id": 1,
"name": "Whien",
"message": "Hello World"
}

》現實中,我們會在文件上蓋章或是簽名

道理是一樣的,既然能夠在現實中透過蓋章或簽名來完成認證,那是否能夠用相同方式來替自己的訊息做簽名呢?

可以的。

》鑰匙回顧

男孩公開鑰匙(0xf3b)男孩私有鑰匙(0x9b1)男孩拿到了女孩的公開鑰匙(0x32a)
女孩公開鑰匙(0x32a)女孩私有鑰匙(0xff3)女孩拿到了男孩的公開鑰匙(0xf3b)

》男孩先將自己的訊息內容透過私有鑰匙簽名

要注意的是訊息內容簽名後,就不能再恢復成原本的明文樣子,但可以拿來比對內容是否有被更改,這方式只能拿來驗證訊息是否有被更改

在範例中我們簽名並使用 sha256 來混亂內容與私鑰,而 0x9b1 為男孩的私有鑰匙。

const {
sign
} = require('crypto');
const signatureMsg = sign('sha256', message, 0x9b1);

signatureMsg

簽名過後的結果,因為透過 sha256 混雜過,所以沒有人可以更動。

》男孩再使用女孩的公開鑰匙來加密簽名訊息

signatureMsg 是男孩簽名完以後的結果,為了讓女孩才看得到,所以要再利用女孩的公開鑰匙來加密簽名訊息,0x32a 為女孩的公開鑰匙。

const {
publicEncrypt
} = require('crypto');
const encFromSign = publicEncrypt(0x32a, signatureMsg);

encFromSign

使用女孩的公開鑰匙所產生的加密訊息,除了有女孩的私有鑰匙,沒有人能夠解密並看到內容。

》女孩收到訊息後,進行解密

女孩安安穩穩地收到訊息後,透過自己的私有鑰匙來完成解密內容,0xff3 為女孩的私有鑰匙。

const {
privateDecrypt
} = require('crypto');
const decToSign = privateDecrypt(0xff3, encFromSign);

decTosign

女孩解密後所獲得的結果,內容就是男孩的簽名訊息

》驗證明文訊息是和簽名訊息一致

因為簽名訊息不可逆,因此可以透過演算法來推算出簽名訊息是否和原始訊息一模一樣。

解密後的原始訊息(message)

{
“id”: 1,
“name”: “Whien”,
“message”: “Hello World”
}

驗證訊息

const {
verify
} = require('crypto');
const messageIsValid = verify('sha256', message, boyKeys.publicKey, decToSign);
console.log(messageIsValid);

messageIsValid

從回傳的 ture/false 即可知道原始訊息是否有被竄改過。

》改一點點內容

如果要驗證這方法是否可行,可以嘗試將原始訊息中內容稍微改一下,就會從回傳看到結果。

{
“id”: 1,
“name”: “Whien”,
“message”: “Today is good day.”
}

True or False ?

〉完整原始碼

Hi 我是懷恩,喜歡探索各種不同的領域,不侷限自己。歡迎透過 FB 或 Email 與我一起交流學習Email: sal95610@gmail.com

--

--

Whien
Whien

Written by Whien

遨遊在硬體與軟體世界中,對於計算機一切事物都充滿好奇及熱情。

No responses yet