Node.js 无法使用nodejs crypto对文件进行签名

Node.js 无法使用nodejs crypto对文件进行签名,node.js,header,signature,private-key,elliptic-curve,Node.js,Header,Signature,Private Key,Elliptic Curve,我已经用nodejs crypto创建了一个私钥,并想用这个密钥对一个文件进行签名。 我的代码如下: var ecdh = crypto.createECDH('brainpoolP512t1'); ecdh.generateKeys(); var key = ecdh.getPrivateKey('buffer'); var data= fs.readFileSync(req.file.path); var sign = cry

我已经用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)
现在我发现了一个不同的错误:

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)
错误:错误:0D07207B:asn1编码例程:asn1_get_对象:头太长
错误(本机)
在Sign.Sign(crypto.js:283:26)
at/…js:37:27
马上。(/…/node_modules/multer/lib/make middleware.js:52:37)
运行回调时(timers.js:578:20)
在tryOnImmediate(timers.js:554:5)
在processImmediate[as_immediateCallback](timers.js:533:5)

为数据签名的密钥必须是有效的PEM编码私钥。DH
getPrivateKey()
函数不返回此格式的密钥,而是返回裸私钥数据

你的选择包括:

  • 通过OpenSSL密钥生成器实用程序或类似工具生成私钥
  • 使用第三方节点模块对私钥进行正确编码,如中所述。使用
    asn1.js
    bn.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);
    

我认为应该有我要签名的文件的文件路径?如果您想从DH私钥生成(在节点内)有效的PEM格式密钥,我现在还添加了一个代码示例。非常感谢!尝试解决方案时出现错误“TypeError:asn1.define不是函数”。您安装了正确的模块吗?它应该是
asn1.js
而不是
asn1
。安装了asn1而不是asn1.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);