Javascript 通过WebCryptoAPI而不是browserified node crypto模块在浏览器中生成ECDH密钥

Javascript 通过WebCryptoAPI而不是browserified node crypto模块在浏览器中生成ECDH密钥,javascript,node.js,cryptography,webcrypto-api,Javascript,Node.js,Cryptography,Webcrypto Api,我有一个非常小的节点脚本来创建公钥/私钥 是否有任何方法可以在客户端执行此操作而不必浏览孔加密模块 var crypto = require('crypto'); var userCurve = crypto.createECDH('prime256v1'); var userPublicKey = userCurve.generateKeys() var userPrivateKey = userCurve.getPrivateKey(); 到目前为止,我已经尝试过: // http

我有一个非常小的节点脚本来创建公钥/私钥 是否有任何方法可以在客户端执行此操作而不必浏览孔加密模块

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

但是当我记录它时,它看起来与节点版本完全不同

让我们进行一次完整的椭圆曲线Diffie-Hellman(ECDH)交换,以在双方之间建立一个共享秘密。Alice使用Node.js,Bob坐在他的浏览器(Chrome或Firefox的最新版本)旁。(无需浏览任何内容。)

(1) Alice生成私钥和公钥

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
Alice's publicKey: 043a3770a8068738ded16c9409e1a6fbf6dde2360ac5b3fd3e5bb8d9fd6adaed6ea83ff5153f58ae13098e86da89df1beb14ef46388d3df76e8fe2ee0ff9e926d5
Bob's publicKey: 04aeceba6ae783c9b705833c2fa8822281f47f6f36bc867e4d398fa7a744d4fc63a010cbce1e6c9ac8858ad376a24ee8551615560f01c8bb63c86335c046b18962
sharedSecret: c26c9f370f001a947d7fec4dc9282d3e9ea718e1de487eb4f6fa7d6f0a311b97
sharedSecret: c26c9f370f001a947d7fec4dc9282d3e9ea718e1de487eb4f6fa7d6f0a311b97
(2) Alice将她的公钥发送给Bob(
043a3770…
)。Bob编写了一些帮助程序,将十六进制字符串转换为
uint8array
,并将缓冲区转换为十六进制字符串

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('')
}
示例输出:

publicKey: 043a3770a8068738ded16c9409e1a6fbf6dde2360ac5b3fd3e5bb8d9fd6adaed6ea83ff5153f58ae13098e86da89df1beb14ef46388d3df76e8fe2ee0ff9e926d5
privateKey: 03ce9cb317c8761699f174943dc9b2d2b7991515b48216a4c677fcf5ee879f2c
Alice's publicKey: 043a3770a8068738ded16c9409e1a6fbf6dde2360ac5b3fd3e5bb8d9fd6adaed6ea83ff5153f58ae13098e86da89df1beb14ef46388d3df76e8fe2ee0ff9e926d5
Bob's publicKey: 04aeceba6ae783c9b705833c2fa8822281f47f6f36bc867e4d398fa7a744d4fc63a010cbce1e6c9ac8858ad376a24ee8551615560f01c8bb63c86335c046b18962
sharedSecret: c26c9f370f001a947d7fec4dc9282d3e9ea718e1de487eb4f6fa7d6f0a311b97
sharedSecret: c26c9f370f001a947d7fec4dc9282d3e9ea718e1de487eb4f6fa7d6f0a311b97
(4) Alice收到Bob的公钥(
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输出:

publicKey: 043a3770a8068738ded16c9409e1a6fbf6dde2360ac5b3fd3e5bb8d9fd6adaed6ea83ff5153f58ae13098e86da89df1beb14ef46388d3df76e8fe2ee0ff9e926d5
privateKey: 03ce9cb317c8761699f174943dc9b2d2b7991515b48216a4c677fcf5ee879f2c
Alice's publicKey: 043a3770a8068738ded16c9409e1a6fbf6dde2360ac5b3fd3e5bb8d9fd6adaed6ea83ff5153f58ae13098e86da89df1beb14ef46388d3df76e8fe2ee0ff9e926d5
Bob's publicKey: 04aeceba6ae783c9b705833c2fa8822281f47f6f36bc867e4d398fa7a744d4fc63a010cbce1e6c9ac8858ad376a24ee8551615560f01c8bb63c86335c046b18962
sharedSecret: c26c9f370f001a947d7fec4dc9282d3e9ea718e1de487eb4f6fa7d6f0a311b97
sharedSecret: c26c9f370f001a947d7fec4dc9282d3e9ea718e1de487eb4f6fa7d6f0a311b97
秘密是共享的(相同的)

(5) 共享秘密通常用于派生一个对称密钥,用于加密Alice和Bob之间的消息(从那以后他们一直愉快地通信)

备注:

  • 通常不需要显示或导出私钥。Alice通常会从步骤(1)继续计算共享密钥(并省略
    Alice.setPrivateKey(alicePrivateKey,'hex')

  • 由于共享密钥最常用于派生对称密钥,因此存在和
    deriveBits
    <这里使用code>deriveBits来说明Alice和Bob确实同意一个共享的秘密


Emh,谢谢,我想。。。不记得我现在想用它做什么了。是2年前的事了。@user1924627您有没有可能帮助解决ApplePay令牌解密问题?