Unable to sign a file with nodejs crypto

匿名 (未验证) 提交于 2019-12-03 02:29:01

问题:

I've created a private Key with nodejs crypto and want to sign a file with this key. My code is following:

var ecdh = crypto.createECDH('brainpoolP512t1');         ecdh.generateKeys();         var key = ecdh.getPrivateKey('buffer');          var data= fs.readFileSync(req.file.path);         var sign = crypto.createSign('sha512');         sign.update(data);         var signature = sign.sign(key, 'hex'); 

But I get the error:

Error: error:0906D06C:PEM routines:PEM_read_bio:no start line     at Error (native)     at Sign.sign (crypto.js:283:26)     at /....js:32:27     at Immediate.<anonymous> (/.../node_modules/multer/lib/make-middleware.js:52:37)     at runCallback (timers.js:578:20)     at tryOnImmediate (timers.js:554:5)     at processImmediate [as _immediateCallback] (timers.js:533:5) 

I know it has something to do with the key format, but I don't know how to fix this. Can anyone help?

UPDATE: I edited the privateKey to fit the pem format:

var KEY_START = '-----BEGIN EC PRIVATE KEY-----\n'; var KEY_END = '\n-----END EC PRIVATE KEY-----';  const ecdh = crypto.createECDH('brainpoolP512t1');             ecdh.generateKeys();             var key =KEY_START + ecdh.getPrivateKey('base64') + KEY_END;                     var data= fs.readFileSync(req.file.path);             const sign = crypto.createSign('sha512');             sign.update(data);             var signature = sign.sign(key, 'hex'); 

And now I geht a different error:

Error: error:0D07207B:asn1 encoding routines:ASN1_get_object:header too long     at Error (native)     at Sign.sign (crypto.js:283:26)     at /...js:37:27     at Immediate.<anonymous> (/.../node_modules/multer/lib/make-middleware.js:52:37)     at runCallback (timers.js:578:20)     at tryOnImmediate (timers.js:554:5)     at processImmediate [as _immediateCallback] (timers.js:533:5) 

回答1:

The key you sign the data with needs to be a valid PEM-encoded private key. The DH getPrivateKey() function does not return a key in this format, it returns the bare private key data.

Your options include:

  • Generating a private key via the OpenSSL key generator utility or similar
  • Using third-party node modules to properly encode the private key as outlined in RFC 5915. Full example using the asn1.js and bn.js modules:

    var crypto = require('crypto');  var asn1 = require('asn1.js'); var BN = require('bn.js');  function toOIDArray(oid) {   return oid.split('.').map(function(s) {     return parseInt(s, 10)   }); }  // Define ECPrivateKey from RFC 5915 var ECPrivateKey = asn1.define('ECPrivateKey', function() {   this.seq().obj(     this.key('version').int(),     this.key('privateKey').octstr(),     this.key('parameters').explicit(0).objid().optional(),     this.key('publicKey').explicit(1).bitstr().optional()   ); });  // Generate the DH keys var ecdh = crypto.createECDH('brainpoolP512t1'); ecdh.generateKeys();  // Generate the PEM-encoded private key var pemKey = ECPrivateKey.encode({   version: new BN(1),   privateKey: ecdh.getPrivateKey(),   // OID for brainpoolP512t1   parameters: toOIDArray('1.3.36.3.3.2.8.1.1.14') }, 'pem', { label: 'EC PRIVATE KEY' });  // Sign data var sign = crypto.createSign('sha512'); sign.update('hello world'); var signature = sign.sign(pemKey, 'hex');  console.log('signature', signature); 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!