2016-04-13 2 views
2

Ich habe ein sehr kleines Knotenscript zum Erstellen eines öffentlichen/privaten Schlüssels Gibt es eine Möglichkeit, dies auf der Client-Seite zu tun, ohne Hole-Krypto zu browsen Modul?Generieren von ECDH-Schlüsseln im Browser über WebCryptoAPI anstelle des vererbten Knotens Krypto-Modul

var crypto = require('crypto'); 

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

Ich habe schon versucht, diese so weit:

// 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); 
}); 

Aber es sieht nichts, wie die Knoten-Version, wenn ich log es

Antwort

2

Lassen Sie uns eine vollständige elliptische Kurve tun Austausch Diffie-Hellman (ECDH) ein gemeinsames Geheimnis zwischen zwei Parteien herzustellen. Alice verwendet Node.js und Bob sitzt in seinem Browser (eine aktuelle Version von Chrome oder Firefox). (Keine Notwendigkeit, irgendetwas zu browserisieren.)

(1) Alice generiert einen privaten und öffentlichen Schlüssel.

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}`) 

Beispiel Ausgabe:

publicKey: 043a3770a8068738ded16c9409e1a6fbf6dde2360ac5b3fd3e5bb8d9fd6adaed6ea83ff5153f58ae13098e86da89df1beb14ef46388d3df76e8fe2ee0ff9e926d5 
privateKey: 03ce9cb317c8761699f174943dc9b2d2b7991515b48216a4c677fcf5ee879f2c 

(2) Alice sendet ihren öffentlichen Schlüssel zu Bob (043a3770...). Bob hat einige Helfer geschrieben, die Hex-Strings in Uint8Arrays und Puffer in Hex-Strings konvertieren.

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) Bob erhält Schlüssel des Alices und berechnet das Geheimnis geteilt

  • Er erzeugt seine eigenen privaten und öffentlichen Schlüssel
  • Er exportiert seinen öffentlichen Schlüssel und sendet sie an Alice
  • Er Importiert Alices öffentlichen Schlüssel
  • Er berechnet das gemeinsame Geheimnis mit seinem privaten und Alices öffentlichen Schlüssel

    // 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) 
        }) 
    

Beispiel Ausgang:

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

(4) empfängt Alice Bob den öffentlichen Schlüssel (04aece...). Sie berechnet auch das gemeinsame Geheimnis.

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 output:

sharedSecret: c26c9f370f001a947d7fec4dc9282d3e9ea718e1de487eb4f6fa7d6f0a311b97 

Die geheime gemeinsam benutzt wird (das gleiche).

(5) Das gemeinsame Geheimnis wird normalerweise verwendet, um einen symmetrischen Schlüssel für die Verschlüsselung von Nachrichten zwischen Alice und Bob abzuleiten (und sie haben glücklich miteinander kommuniziert).

Bemerkungen:

  • Normalerweise ist es nicht erforderlich oder privaten Schlüssel zu exportieren anzuzeigen. Alice würde typischerweise die Berechnung des gemeinsamen Geheimnisses von Schritt (1) fortsetzen (und alice.setPrivateKey(alicePrivateKey, 'hex') weglassen).

  • Da das gemeinsame Geheimnis am häufigsten verwendet wird, um einen symmetrischen Schlüssel abzuleiten, können window.crypto.subtle.deriveKey und deriveBits weggelassen werden. deriveBits wurde hier verwendet, um zu illustrieren, dass Alice und Bob tatsächlich einem gemeinsamen Geheimnis zustimmten.

+0

Emh, danke ich denke ... erinnere mich nicht, was ich jetzt damit machen wollte. War vor 2 Jahren. – Endless

Verwandte Themen