2016-09-26 85 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