【问题标题】:Computing a ECDH Shared Secret in JavaScript在 JavaScript 中计算 ECDH 共享密钥
【发布时间】:2014-10-27 19:12:07
【问题描述】:

我需要使用 ECC 密钥和 ECDH 在 JavaScript 中计算共享密钥。我看到两个可能的项目可以做到这一点,但我不确定要追求哪一个:。

  1. https://code.google.com/p/end-to-end
  2. https://github.com/bitwiseshiftleft/sjcl

1) 是一个 chrome 扩展,所以我认为这意味着它不会在其他浏览器中运行。 2) 有人对 SJCL 有疑问,表示他们认为这是使用 ECMQV 而不是普通的 ECDH (Can't bridge Elliptic Curve Diffie-Hellman with javascript)。

有人可以为我的实施推荐一个好的行动方案吗?选项 3(首选选项):我有一种预感,可能会直接在此处包含共享秘密实现:https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/src/ecdsa.js

这是在服务器上创建共享密钥的 C++ 代码:

void * ecies_key_derivation(const void *input, size_t ilen, void *output, size_t *olen) 
    {
        *olen = SHA512_DIGEST_LENGTH;
        return (void*)SHA512((const unsigned char*)input, ilen, (unsigned char*)output);
    }
...
fc::sha512 shared_secret;
ECDH_compute_key( (unsigned char*)&shared_secret, sizeof(shared_secret), EC_KEY_get0_public_key(recipient.my->_key), my->_key, ecies_key_derivation );  

【问题讨论】:

  • 我写过 Tom 在他的演示中支持 secp256k1 曲线:www-cs-students.stanford.edu/~tjw/jsbn/ecdh.html
  • 我刚刚发现了这个:github.com/indutny/elliptic
  • 我看到很多指针和研究,+ 代码块(实现 ECIES,而不是 ECDH,虽然 ECIES 基于 ECDH)但是你的 JavaScript 代码在哪里?你的问题在哪里?
  • 您引用的链接中没有提及 ECMQV。
  • 感谢您的反馈。这是一个很好的健全性检查。这个看起来与 C++ 兼容。我将尝试移植此代码并查看它是否有效:github.com/bitpay/bitcore/blob/master/lib/common/ECIES.js ... 请注意 ECIES.kdf 方法正在S 上运行 sha512 .. 我认为这是共享密钥。

标签: javascript cryptography


【解决方案1】:

显然这需要巩固,但至少可以工作!

选项 1 是特定于 chrome 的: https://bugzilla.mozilla.org/show_bug.cgi?id=1022106 “粗略看一下代码(git clone-able from git clone https://code.google.com/p/end-to-end/),它似乎被设计成一个仅限 Chrome 的插件”

选项 2 使用 bitcore(bitcore 在幕后使用 sjcl),如下所示:

    # npm install bitcore
    ECIES = require '../node_modules/bitcore/lib/ECIES'
    ot_pubkey = new Buffer(onetime_public_key, 'hex')
    my_privkey = new Buffer(d_receiver_hex, 'hex')
    ecies = new ECIES.encryptObj ot_pubkey, new Buffer(''), my_privkey
    S = ecies.getSfromPubkey()
    console.log 'bitcore sharedsecret\t',S.toString 'hex'
    S_kdf_buf = ECIES.kdf(S)

    console.log 'bitcore sharedsecret kdf\t',S_kdf_buf.toString 'hex'

另外 elliptic.js 工作,它使用它自己的代码,包括 bn.js 用于大数字(同一作者):

    # git clone https://github.com/indutny/elliptic.git
    elliptic = require('../elliptic/lib/elliptic.js')

    # npm install bn.js
    bn = require('bn.js')

    #Providing ecies_key_derivation https://github.com/indutny/elliptic/issues/9
    ec = new elliptic.ec('secp256k1')

    s0 = ec.keyPair(onetime_private_key, 'hex')

    # ../testnet/config/genesis_private_keys.txt

    s1 = ec.keyPair(d_receiver_hex, "hex")

    sh0 = s0.derive(s1.getPublic())
    sh1 = s1.derive(s0.getPublic())    
    assert.equal sh0.toString(16), sh1.toString(16), "shared secret did not match"

    shared_secret = "0"+sh0.toString(16) #### only works for this shared secret (bn.js::toString(16))

此时,我让这些库能够正确生成共享机密。对于解密,我最终使用了 crypto-js。

    # https://code.google.com/p/crypto-js/#Custom_Key_and_IV
    # see wallet_records.cpp master_key::decrypt_key
    CryptoJS.AES.decrypt(
      ciphertext: cipher
      salt: null
    , @key,
      iv: @iv
    )

对于解密,我需要一个 256 位 IV(初始化向量)来执行任务,以便在更新之前将 SJCL 排除在外 (https://github.com/bitwiseshiftleft/sjcl/issues/197)。此外,虽然我不确定这是否是我的错误,但我也没有太多运气使用 elliptic.js 解密。

【讨论】:

    猜你喜欢
    • 2021-08-09
    • 2017-10-28
    • 1970-01-01
    • 1970-01-01
    • 2019-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多