2016-09-26 66 views
1

我已经使用nodejs crypto创建了一个私钥并希望用此密钥签署文件。 我的代码如下:无法使用nodejs crypto签署文件

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

但我得到的错误:

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) 

我知道它是与密钥格式,但我不知道如何解决这个问题。谁能帮忙?

更新: 我编辑的专用密钥,以适应PEM格式:

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

现在我geht一个不同的错误:

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) 

回答

3

关键你签订的需求数据是一个有效的PEM编码私钥。 DH getPrivateKey()函数不返回此格式的密钥,它将返回裸露的私钥数据。

选项包括:

  • 产生从OpenSSL的密钥生成器实用程序或类似
  • 使用第三方节点模块,以正确编码私钥作为RFC 5915概述私钥。采用全例如asn1.jsbn.js模块:

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

我想应该站在我要签名的文件的文件路径? – nolags

+0

我错过了,我已经更新了我的答案。 – mscdex

+0

我现在还添加了一个代码示例,如果您想从DH私钥生成(在节点内)有效的PEM格式的密钥。 – mscdex