Skip to content

Signing with a ecdh type private key #18147

Description

@ikouchiha47

I didn't know where to ask this. But I needed to ask.

The problem is after generating public private keys with ecdh, I am trying to use sign.sign and it doesn't seem to work.
At first I just wrapped the alice.getPrivateKey('base64') inside a -----BEGIN EC PRIVATE KEY----- and -----END EC PRIVATE KEY----- but that resulted in asn1 too long

So I split the private key at 64 characters, and that resulted in Error: error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag
I also tried spliting the `alice.generateKeys().toString('base64') and wrapping it in begin end block. But that too results in the same error.

Here are the codes:

try1.js

const crypto = require('crypto');

// Generate Alice's keys...
const alice = crypto.createECDH('secp521r1');
const aliceKeys = alice.generateKeys();

let pKey = `-----BEGIN EC PRIVATE KEY-----\n${aliceKeys.toString('base64').match(/.{1,64}/g).join('\n')}\n-----END EC PRIVATE KEY-----`;

console.log(pKey)

const sign = crypto.createSign('ecdsa-with-SHA1');
sign.update('some data to sign');
console.log(sign.sign(pkey, 'hex'))

try2.js

const alice = crypto.createECDH('secp521r1');
alice.generateKeys();
const alicePKey = alice.getPrivateKey('base64')

let privateKey = `-----BEGIN EC PRIVATE KEY-----\n${alicePKey.match(/.{1,64}/g).join('\n')}\n-----END EC PRIVATE KEY-----`;

console.log(privateKey)

const sign = crypto.createSign('ecdsa-with-SHA1');
sign.update('some data to sign');

console.log(sign.sign(privateKey, 'hex'))

The error being:

crypto.js:286
  var ret = this._handle.sign(toBuf(key), null, passphrase);
                         ^

Error: error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag
    at Sign.sign (crypto.js:286:26)
    at Object.<anonymous> (/home/argentum/dev/dfh.js:15:6)
    at Module._compile (module.js:571:32)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:488:32)
    at tryModuleLoad (module.js:447:12)
    at Function.Module._load (module.js:439:3)
    at Module.runMain (module.js:605:10)
    at run (bootstrap_node.js:423:7)
at startup (bootstrap_node.js:147:9)

But if I generate the pem file like:

openssl ecparam -genkey -name secp521r1 -noout -out ecdsaprivate.pem

which is from where I copied the begin end blocks. And I read the file in ascii and pass that to the sign method. It works like butter.

What am I doing wrong

Activity

  1. added
    questionIssues asking questions about Node.js.
    cryptoIssues and PRs related to the crypto subsystem.
    on Jan 15, 2018
  2. bnoordhuis commented on Jan 15, 2018

    @bnoordhuis
    Member

    .getPrivateKey() returns just the private key, openssl ecparam -genkey writes the private key wrapped in a PEM-encoded ASN.1 container:

    $ openssl ecparam -genkey -name secp521r1 -noout | openssl asn1parse
        0:d=0  hl=3 l= 219 cons: SEQUENCE          
        3:d=1  hl=2 l=   1 prim: INTEGER           :01
        6:d=1  hl=2 l=  65 prim: OCTET STRING      [HEX DUMP]:E713D72B75731D8ED64E2EF6DB54E0EB0CD4AC3FE5BF34270E348DD7CDC3D1428A91C0ABF45B89790D9EC5D87DC4768F13DB5164A48DD2B2BF92B545B9936C85B5
       73:d=1  hl=2 l=   7 cons: cont [ 0 ]        
       75:d=2  hl=2 l=   5 prim: OBJECT            :secp521r1
       82:d=1  hl=3 l= 137 cons: cont [ 1 ]        
       85:d=2  hl=3 l= 134 prim: BIT STRING        
    

    That 65 byte octet string is the private key.

    Node.js currently has no direct support for constructing that container but there's probably a library for it on npm (asn1.js?) and worst case, you can construct it yourself, the format is not hugely complex.

    I'll close this out, see #15116 for the feature request. Please post follow-up questions to the help repo.

  3. skerit commented on Feb 23, 2018

    @skerit

    Why doesn't the Sign#sign method allow the use of a Buffer to pass along the private key to use? It seems like quite a waste to first add a wrapper Sign#sign needs to unwrap anyway.

  4. bnoordhuis commented on Feb 23, 2018

    @bnoordhuis
    Member

    @skerit Just raw bytes doesn't tell you what kind of key it is or what params it has. Look up how many openssl apis start with 'EVP_PKEY_' and you'll get a feel for the phase space. :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    cryptoIssues and PRs related to the crypto subsystem.questionIssues asking questions about Node.js.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions