Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
895 views
in Technique[技术] by (71.8m points)

node.js - Unable to sign a file with nodejs crypto

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-----
';
var KEY_END = '
-----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)
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
...