2016-04-13 14 views
2

公開鍵/秘密鍵を作成する非常に小さなノードスクリプトがあります ホール暗号をブラウズしなくてもクライアント側で行う方法はありますかモジュール?ブラウザで公開鍵暗号化モジュールの代わりにWebCryptoAPIを使用してECDH鍵を生成

var crypto = require('crypto'); 

var userCurve = crypto.createECDH('prime256v1'); 
var userPublicKey = userCurve.generateKeys() 
var userPrivateKey = userCurve.getPrivateKey(); 

私はこれまでのところ、これを試してみました:

// https://github.com/diafygi/webcrypto-examples#ecdh---generatekey 
window.crypto.subtle.generateKey(
    { 
     name: "ECDH", 
     namedCurve: "P-256", //can be "P-256", "P-384", or "P-521" 
    }, 
    true, //whether the key is extractable (i.e. can be used in exportKey) 
    ["deriveKey", "deriveBits"] //can be any combination of "deriveKey" and "deriveBits" 
) 
.then(function(key){ 
    //returns a keypair object 
    console.log(key); 
    console.log(key.publicKey); 
    console.log(key.privateKey); 
}) 
.catch(function(err){ 
    console.error(err); 
}); 

をしかし、それは、私はそれが

答えて

2

のは、完全な楕円曲線のDiffie-Hellmanの(ECDH)交換をやってみましょうログインしたときにノードのバージョンのようなものに見えるん2人の当事者間で共有秘密を確立する。 AliceはNode.jsを使用し、Bobは自分のブラウザ(ChromeまたはFirefoxの最新バージョン)に座っています。 (何もブラウズする必要はありません)

(1)アリスは秘密鍵と公開鍵を生成します。

const crypto = require('crypto'); 

const alice = crypto.createECDH('prime256v1'); 
alice.generateKeys() 

const alicePublicKey = alice.getPublicKey('hex') 
const alicePrivateKey = alice.getPrivateKey('hex') 

console.log(`publicKey: ${alicePublicKey}`) 
console.log(`privateKey: ${alicePrivateKey}`) 

出力例:

publicKey: 043a3770a8068738ded16c9409e1a6fbf6dde2360ac5b3fd3e5bb8d9fd6adaed6ea83ff5153f58ae13098e86da89df1beb14ef46388d3df76e8fe2ee0ff9e926d5 
privateKey: 03ce9cb317c8761699f174943dc9b2d2b7991515b48216a4c677fcf5ee879f2c 

(2)アリスはボブ(043a3770...)に彼女の公開鍵を送信します。 Bobは、ヘキサ・ストリングをUint8Arraysに変換し、バッファを16進ストリングに変換するヘルパーを作成しました。

const hex2Arr = str => { 
    if (!str) { 
     return new Uint8Array() 
    } 
    const arr = [] 
    for (let i = 0, len = str.length; i < len; i+=2) { 
     arr.push(parseInt(str.substr(i, 2), 16)) 
    } 
    return new Uint8Array(arr) 
} 

const buf2Hex = buf => { 
    return Array.from(new Uint8Array(buf)) 
     .map(x => ('00' + x.toString(16)).slice(-2)) 
     .join('') 
} 

(3)ボブは、彼は彼

  • を自分の公開鍵をエクスポートし、アリス
  • に送信
  • 彼自身の秘密鍵と公開鍵を生成し、アリスの鍵を受け取り、共有秘密に

    • を計算Aliceの公開鍵をインポートする
    • 彼は自分の秘密鍵とAliceの公開鍵を使って計算する

      // Alice's public key (received over an [insecure] connection) 
      const alicePublicKeyHex = '043a3770a8068738ded16c9409e1a6fbf6dde2360ac5b3fd3e5bb8d9fd6adaed6ea83ff5153f58ae13098e86da89df1beb14ef46388d3df76e8fe2ee0ff9e926d5' 
      const alicePublicKey = hex2Arr(alicePublicKeyHex) 
      console.log(`Alice's publicKey: ${alicePublicKeyHex}`) 
      
      let bob = null 
      
      // generate Bob's private and public key 
      window.crypto.subtle.generateKey(
          { 
           name: 'ECDH', 
           namedCurve: 'P-256' 
          }, 
          false, // no need to make Bob's private key exportable 
          ['deriveKey', 'deriveBits']) 
          .then(bobKey => { 
           bob = bobKey 
           // export Bob's public key 
           return window.crypto.subtle.exportKey(
            'raw', bobKey.publicKey 
           ) 
          }) 
          .then(bobPublicKeyExported => { 
           const bobPublicKeyHex = buf2Hex(bobPublicKeyExported) 
           // display and send Bob's public key to Alice 
           console.log(`Bob's publicKey: ${bobPublicKeyHex}`) 
      
           // import Alice's public key 
           return window.crypto.subtle.importKey(
            'raw', 
            alicePublicKey, 
            { 
             name: 'ECDH', 
             namedCurve: 'P-256' 
            }, 
            true, 
            []) 
          }) 
          .then(aliceKeyImported => { 
           // use Alice's imported public key and 
           // Bob's private key to compute the shared secret 
           return window.crypto.subtle.deriveBits(
            { 
             name: 'ECDH', 
             namedCurve: 'P-256', 
             public: aliceKeyImported 
            }, 
            bob.privateKey, 
            256) 
          }) 
          .then(sharedSecret => { 
           const sharedSecretHex = buf2Hex(sharedSecret) 
           console.log(`sharedSecret: ${sharedSecretHex}`) 
          }) 
          .catch(err => { 
           console.log(err) 
          }) 
      

    出力例:

    Alice's publicKey: 043a3770a8068738ded16c9409e1a6fbf6dde2360ac5b3fd3e5bb8d9fd6adaed6ea83ff5153f58ae13098e86da89df1beb14ef46388d3df76e8fe2ee0ff9e926d5 
    Bob's publicKey: 04aeceba6ae783c9b705833c2fa8822281f47f6f36bc867e4d398fa7a744d4fc63a010cbce1e6c9ac8858ad376a24ee8551615560f01c8bb63c86335c046b18962 
    sharedSecret: c26c9f370f001a947d7fec4dc9282d3e9ea718e1de487eb4f6fa7d6f0a311b97 
    

    (4)アリスはボブの公開鍵(04aece...)を受信します。彼女は共有の秘密も同様に計算します。

    const crypto = require('crypto') 
    const alice = crypto.createECDH('prime256v1') 
    
    // Alice's privateKey (generated previously) 
    const alicePrivateKey = '937cdd11062b612ff3cb3e4a3c183254b9728b4c8c3a64de799ed196b672734b' 
    
    // Bob's publicKey transmitted to Alice 
    const bobPublicKey = '04aeceba6ae783c9b705833c2fa8822281f47f6f36bc867e4d398fa7a744d4fc63a010cbce1e6c9ac8858ad376a24ee8551615560f01c8bb63c86335c046b18962' 
    
    // set Alice's private key (not needed if continuing from (1)) 
    alice.setPrivateKey(alicePrivateKey, 'hex') 
    
    const sharedSecret = alice.computeSecret(bobPublicKey, 'hex', 'hex') 
    console.log(`sharedSecret: ${sharedSecret}`) 
    

    Examle出力:

    sharedSecret: c26c9f370f001a947d7fec4dc9282d3e9ea718e1de487eb4f6fa7d6f0a311b97 
    

    秘密が共有されている(同)。

    (5)共有秘密は、通常、アリスとボブ間のメッセージを暗号化するための共通鍵を導出するために使用されます。

    備考:

    • 通常表示または秘密キーをエクスポートする必要はありません。アリスは、通常、ステップ(1)からの共有秘密の計算を継続する(そして、alice.setPrivateKey(alicePrivateKey, 'hex')を省略する)。

    • 共有秘密は、対称鍵を導出するために最も頻繁に使用されるため、window.crypto.subtle.deriveKeyderiveBitsを省略できます。 AliceとBobが確かに共有秘密に合意したことを示すためにここではderiveBitsを使用しました。

  • +0

    Emh、ありがとうございました...私は今ここで何をしたいのか覚えていません。 2年前だった。 – Endless

    関連する問題