《Nodejs開發加密貨幣》之十:三張圖讓你全面掌握加密解密技術

關於

《Nodejs開發加密貨幣》,是一個加密貨幣產品的詳細開發文檔,涉及到使用Nodejs開發產品的方方面面,從前端到後臺、從服務器到客戶端、從PC到移動、加密解密等各個環節。代碼完全開源、文章免費分享。 相關資源見 http://ebookchain.org

QQ交流羣: 185046161

前言

加密解密技術,涉及面很廣,這裏,把前人的研究成果彙總起來,通過圖表的形式來幫助記憶和篩選,方便日後使用。內容主要包括兩個方面,一個是場景與算法,一個是Nodejs的相關模塊或組件。共三張腦圖,具體請看:

1.加密解密縱覽

下面這張圖,是在 《密碼學一小時必知》(見參考)基礎上完成的,原作者是Colin Percival,密碼學方面的專家,FreeBSD項目的安全長官,Tarsnap在線備份服務的創始人,scrypt密鑰衍生算法的作者,非常值得參考學習。譯者是 @byronhe ,翻譯貢獻這樣的好文,包括下面有關論述場景與算法的實踐指南,值得去爲他點贊。

這張圖,可以告訴你密碼學中的概念,目的,案例,以及最佳的實踐經驗。

加密解密.png

2.場景與算法

這張圖,是基於 《現代密碼學實踐指南(2015年)》(見參考) 完成的。可以說,在上一張圖的基礎上,更加具體,特別是對於場景的描述,讓碼農可以更加方便的作出正確的選擇,值得擁有。其中,標註序號的,是有優先級的。

場景與算法選擇.png

3.Nodejs中的的加密和解密、簽名與認證

這張圖,主要參考了官方文檔及其他一些文檔(見參考),按照我個人的理解畫得。如果你使用Nodejs,基本上拿來看看圖解,就能直接用了。特別是,默認選擇了ed255519組件,如果你看了上面兩篇實踐,就知道這是簽名與認證最好的選擇,因此這裏可以肯定的說,Crypto模塊的簽名與認證還是暫時不要用吧。Ebookcoin就是這麼實踐的,具體見下一篇介紹。另一個是Natrium組件,也可以用於簽名和認證,但主要是用來非對稱加密和解密的。這張腦圖裏的三個組合,按照上面的實踐經驗來說,應該是當前Nodejs加解密應用領域的最佳組合方案。

Nodejs中的的加密和解密、簽名與認證.png

4.趣味實踐

還是用在《在Nodejs中使用加密解密技術》裏的的例子吧,設定角色,男生叫Bob,他的女友叫Alice。

場景

Bob想向女友表達埋藏已久的心聲“I love you!”,但礙於男人的顏面(男人都這樣嗎?),不好意思當面說出口,只好加密傳輸。這裏基於一個可行的假設,就是他們已經擁有彼此的公鑰,或者可以簡單獲得。

需求

  • 加密:不能讓別人看到信息;
  • 解密:女友可以恢復並查看;
  • 簽名:Bob可以簽名信息,確保不被篡改;
  • 認證:女友收到信息,可以驗明正身,確認是Bob所發,而不是別人的惡作劇。

方案

利用以上三張圖,我們可以很快拿出技術方案。

  • 加密與解密技術:第二張圖顯示說,這種加密之後又解密原文的場景非常少見。技術上,最好使用NaCl,其次是libsodium(背後仍然是NaCl),但是搜索了一下github,Nodejs社區還沒有相關NaCl穩定的封裝包,libsodium倒是有一個Natrium(但是,寫作本文時,連安裝都沒有成功,有驗證成功的,請告訴我一聲)。因此,只能選擇使用Crypto簡單加密和解密。
  • 簽名與驗證技術:當然最好的選擇是ed25519了。

編碼

新建一個簡單的Nodejs工程, 代碼在這裏: https://github.com/imfly/nodejs-practice/blob/master/crypto/index.js

(1)生成密鑰對

Bob沒有使用隨機字符串,而是使用一個密碼,並採取SHA256算法生成密鑰對,請看思維導圖,有關hash的部分。

var crypto = require('crypto');
var ed25519 = require('ed25519');

var bobsPassword = 'This is my password, you don`t guess it!';
var hash = crypto.createHash('sha256').update(bobsPassword).digest();
var bobKeypair = ed25519.MakeKeypair(hash);

(2)給信息加密和簽名

通常是先加密後簽名。

這裏使用Crypto給信息進行了簡單加密,把Bob的公鑰作爲加密鍵值(但是既然是公鑰,誰會不知道呢,除非Bob只把公鑰給了Alice),可能還得Bob告訴Alice使用什麼算法來解密。

var message = 'Hi Alice, I love you!';
var msgCiphered = cipher('aes192', bobKeypair.publicKey, message); //公鑰進行加密,如果是Natrium,這裏就是私鑰加密
var signature = ed25519.Sign(new Buffer(msgCiphered, 'utf8'), bobKeypair.privateKey); //私鑰進行簽名

(3)給Alice發送簽名信息

這個就各顯神通了。

(4)Alice驗證並解密

通常是先驗證後解密。

作爲Bob的好朋友,Alice有他的公鑰。

if (ed25519.Verify(new Buffer(msgCiphered, 'utf8'), signature, bobKeypair.publicKey)) {
    // 驗證函數返回了true,通過驗證
  var msg = decipher('aes192', bobKeypair.publicKey, msgCiphered);  //使用Bob的公鑰解密

    console.log('簽名合法,信息來自Bob!');
  console.log('Bob said: ', msg); //顯示信息
} else {
    // 驗證函數返回了false,肯定不是Bob的信息.
    console.log('簽名不合法!');
}

(5)補充代碼

上面用到的Crypto的加密解密方法:

//解密
function (algorithm, key, buffer){
    var encrypted = "";
    var cip = crypto.createCipher(algorithm, key);
    encrypted += cip.update(buffer, 'utf8', 'hex');
    encrypted += cip.final('hex');
    return encrypted;
}

//解密
function decipher(algorithm, key, encrypted){
    var decrypted = "";
    var decipher = crypto.createDecipher(algorithm, key);
    decrypted += decipher.update(encrypted, 'hex', 'utf8');
    decrypted += decipher.final('utf8');
    return decrypted;
}

(6)運行實例

使用下面的命令,可以運行上述代碼:

$ git clone https://github.com/imfly/nodejs-practice
$ cd nodejs-practice
$ npm install
$ node crypto/

輸出結果:

簽名合法,信息來自Bob!
Bob said:  Hi Alice, I love you!

鏈接

本系列文章即時更新,若有興趣,可通過Star收藏,^-^

本源文地址: https://github.com/imfly/bitcoin-on-nodejs

電子書閱讀: http://bitcoin-on-nodejs.ebookchain.org

參考

Ed25519第三方組件

Ed25519官方網站

現代密碼學實踐指南(2015年)

密碼學一小時必知

淺談nodejs中的Crypto模塊

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