Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Signing with a ecdh type private key #18147

Closed
ikouchiha47 opened this issue Jan 14, 2018 · 3 comments
Closed

Signing with a ecdh type private key #18147

ikouchiha47 opened this issue Jan 14, 2018 · 3 comments
Labels
crypto Issues and PRs related to the crypto subsystem. question Issues that look for answers.

Comments

@ikouchiha47
Copy link

ikouchiha47 commented Jan 14, 2018

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

@bnoordhuis bnoordhuis added question Issues that look for answers. crypto Issues and PRs related to the crypto subsystem. labels Jan 15, 2018
@bnoordhuis
Copy link
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.

@skerit
Copy link

skerit commented Feb 23, 2018

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.

@bnoordhuis
Copy link
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
Labels
crypto Issues and PRs related to the crypto subsystem. question Issues that look for answers.
Projects
None yet
Development

No branches or pull requests

3 participants