關於
《Nodejs開發加密貨幣》,是一個加密貨幣產品的詳細開發文檔,涉及到使用Nodejs開發產品的方方面面,從前端到後臺、從服務器到客戶端、從PC到移動、加密解密等各個環節。代碼完全開源、文章免費分享。 相關資源見 http://ebookchain.org
QQ交流羣: 185046161
前言
加密解密技術,涉及面很廣,這裏,把前人的研究成果彙總起來,通過圖表的形式來幫助記憶和篩選,方便日後使用。內容主要包括兩個方面,一個是場景與算法,一個是Nodejs的相關模塊或組件。共三張腦圖,具體請看:
1.加密解密縱覽
下面這張圖,是在 《密碼學一小時必知》(見參考)基礎上完成的,原作者是Colin Percival,密碼學方面的專家,FreeBSD項目的安全長官,Tarsnap在線備份服務的創始人,scrypt密鑰衍生算法的作者,非常值得參考學習。譯者是 @byronhe ,翻譯貢獻這樣的好文,包括下面有關論述場景與算法的實踐指南,值得去爲他點贊。
這張圖,可以告訴你密碼學中的概念,目的,案例,以及最佳的實踐經驗。
2.場景與算法
這張圖,是基於 《現代密碼學實踐指南(2015年)》(見參考) 完成的。可以說,在上一張圖的基礎上,更加具體,特別是對於場景的描述,讓碼農可以更加方便的作出正確的選擇,值得擁有。其中,標註序號的,是有優先級的。
3.Nodejs中的的加密和解密、簽名與認證
這張圖,主要參考了官方文檔及其他一些文檔(見參考),按照我個人的理解畫得。如果你使用Nodejs,基本上拿來看看圖解,就能直接用了。特別是,默認選擇了ed255519
組件,如果你看了上面兩篇實踐,就知道這是簽名與認證最好的選擇,因此這裏可以肯定的說,Crypto模塊的簽名與認證還是暫時不要用吧。Ebookcoin
就是這麼實踐的,具體見下一篇介紹。另一個是Natrium
組件,也可以用於簽名和認證,但主要是用來非對稱加密和解密的。這張腦圖裏的三個組合,按照上面的實踐經驗來說,應該是當前Nodejs加解密應用領域的最佳組合方案。
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