Node.js 橢圓曲線加密庫------eccrypto

eccrypto爲用於瀏覽器和Node的橢圓曲線加密庫。

 

動機

沒有任何同構的ECC庫爲Node.js和瀏覽器提供ECDSA、ECDH和ECIES,並且使用最快的實現(例如secp256k1-node比其他庫快得多,但只能在Node.js上使用)。所以eccrypto是一種創造的嘗試。

 

實現細節

在Browserify的幫助下,eccrypto使用相同的API爲瀏覽器和Node.js提供了不同的實現。因爲WebCryptoAPI定義了異步promise-drive的API,所以Node的實現也需要使用promises 。

在可能的情況下,使用Node.js加密模塊/庫綁定,在可能的情況下使用WebCryptoAPI,只有secp256k1曲線,只有sha-512(Kdf),hmac-sha-256(Hmac)和aes-256-cbc,用於ECIES壓縮密鑰支持。

本地加密API限制

crypto

ECDH僅在Node 0.11+中運行(請參閱https://github.com/joyent/node/pull/5854),ECDSA僅支持PEM格式的密鑰(請參見https://github.com/joyent/node/issues/6904 ),根本不支持ECIES。

WebCryptoAPI

Chrome只在Windows上支持ECDSA和ECDH(參見bug 338883),Firefox不支持ECDSA和ECDH(僅在36.0+中修復,請參見bug 1034854;請參見功能矩陣),而且WebCryptoAPI草案中根本沒有定義ECIES。另外,WebCryptoAPI目前只定義了NIST推薦的曲線,這意味着不支持Secp256k1(K-256)曲線(另請參閱:[1],[2])。因此,我們在Node中使用seck256k1庫進行ECDSA,在瀏覽器中使用橢圓庫實現ECDSA和ECDH,並藉助本機密碼API手動實現ECIES。

 

可能的未來目標

支持其他曲線/kdf/mac/對稱加密方案

 

用法

ECDSA

//適用於數字貨幣賬戶體系
var crypto = require("crypto");   //官方庫
var eccrypto = require("eccrypto"); //橢圓曲線加密庫
 
//一個新的隨機的32字節私鑰。
var privateKey = eccrypto.generatePrivate();
//私鑰對應的未壓縮(65字節)公鑰。
var publicKey = eccrypto.getPublic(privateKey);
//字符串
var str = "message to sign";
//使用sha256哈希字符串
var msg = crypto.createHash("sha256").update(str).digest();
//使用私鑰簽名哈希數據
eccrypto.sign(privateKey, msg).then(function(sig) {
  console.log("Signature in DER format:", sig);
  //使用公鑰驗證簽名數據和哈希數據是否匹配
  eccrypto.verify(publicKey, msg, sig).then(function() {
    console.log("Signature is OK");
  }).catch(function() {
    console.log("Signature is BAD");
  });
});

ECDH

//適用於點對點通信加密
var eccrypto = require("eccrypto");
//獲得兩對公私玥 
var privateKeyA = eccrypto.generatePrivate();
var publicKeyA = eccrypto.getPublic(privateKeyA);
var privateKeyB = eccrypto.generatePrivate();
var publicKeyB = eccrypto.getPublic(privateKeyB);
//使用A私鑰和B公鑰生成雙方通信的加密私鑰
eccrypto.derive(privateKeyA, publicKeyB).then(function(sharedKey1) {
 //使用B的私鑰和A的公鑰生成雙方通信的加密私鑰
  eccrypto.derive(privateKeyB, publicKeyA).then(function(sharedKey2) {
    //ECDH算法該加密私鑰應該相等
    console.log("Both shared keys are equal:", sharedKey1, sharedKey2);
  });
});

ECIES

//適用於對數據進行非對稱加密
var eccrypto = require("eccrypto");
//生成兩對公私鑰
var privateKeyA = eccrypto.generatePrivate();
var publicKeyA = eccrypto.getPublic(privateKeyA);
var privateKeyB = eccrypto.generatePrivate();
var publicKeyB = eccrypto.getPublic(privateKeyB);
 
//使用B的公鑰加密字符串字節
eccrypto.encrypt(publicKeyB, Buffer.from("msg to b")).then(function(encrypted) {
  //使用B的私鑰解密字符串字節
  eccrypto.decrypt(privateKeyB, encrypted).then(function(plaintext) {
    console.log("Message to part B:", plaintext.toString());
  });
});
 
//使用A的公鑰加密字符串字節
eccrypto.encrypt(publicKeyA, Buffer.from("msg to a")).then(function(encrypted) {
  //使用A的私鑰解密字符串字節
  eccrypto.decrypt(privateKeyA, encrypted).then(function(plaintext) {
    console.log("Message to part A:", plaintext.toString());
  });
});

 

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