代码之家  ›  专栏  ›  技术社区  ›  Josh Peak

NodeJS生成用于签名和验证消息的有效PEM密钥

  •  4
  • Josh Peak  · 技术社区  · 7 年前

    上下文

    https://nodejs.org/api/tls.html#tls_tls_ssl_concepts

    openssl genrsa -out ryans-key.pem 2048
    

    将产生:

    -----BEGIN RSA PRIVATE KEY-----
    base64 encoded magic here...
    -----END RSA PRIVATE KEY-----
    

    我可以成功地使用 Sign 类对消息进行加密签名:

    https://nodejs.org/api/crypto.html#crypto_class_sign

    const crypto = require('crypto');
    const sign = crypto.createSign('RSA-SHA256');
    
    sign.update('some data to sign');
    
    const privateKey = `Insert magic value from above`;
    console.log(sign.sign(privateKey, 'base64'));
    

    const crypto = require('crypto');
    const dhke = crypto.createDiffieHellman(2048);
    dhke.generateKeys();
    const private_pem = `-----BEGIN RSA PRIVATE KEY-----
    ${dhke.getPrivateKey('base64')}
    -----END RSA PRIVATE KEY-----`;
    console.log(private_pem);
    
    const sign = crypto.createSign('RSA-SHA256');
    sign.update('some data to sign');
    
    const signature = sign.sign(private_pem, 'base64');
    console.log(signature);
    

    获取以下错误:

    Error: error:0D07207B:asn1 encoding routines:ASN1_get_object:header too long
        at Sign.sign (internal/crypto/sig.js:84:26)
    ...
    

    问题

    如何使用 crypto 在NodeJS中实现什么 openssl 命令行工具正在执行(或另一个NPM模块)以创建有效的PEM格式的公钥/私钥对,这是 标志 上课?

    类似的悬而未决的问题

    以下是开始完成工作的解决方案,这要感谢 the accepted answer JacobTDC 其中nodejsv10.12.0添加了这个特性。

    const crypto = require('crypto'); const sign = crypto.createSign('RSA-SHA256');
    
    sign.update('some data to sign');
    
    // $ openssl genrsa -out ryans-key.pem 2048 
    // const privateKey = `Insert magic value from above`;
    
    const { generateKeyPairSync } = require('crypto'); 
    const { publicKey, privateKey } = generateKeyPairSync('rsa', 
    {   modulusLength: 2048,  // the length of your key in bits   
        publicKeyEncoding: {
          type: 'spki',       // recommended to be 'spki' by the Node.js docs
          format: 'pem'   
        },   
        privateKeyEncoding: {
          type: 'pkcs8',      // recommended to be 'pkcs8' by the Node.js docs
          format: 'pem',
          //cipher: 'aes-256-cbc',   // *optional*
          //passphrase: 'top secret' // *optional*   
      } 
    }); 
    console.log(privateKey); 
    console.log(sign.sign(privateKey, 'base64'));
    
    2 回复  |  直到 7 年前
        1
  •  8
  •   JacobTDC    7 年前

    从Node.js v10.12.0开始,您可以使用 crypto.generateKeyPair crypto.generateKeyPairSync .

    const { generateKeyPairSync } = require('crypto');
    const { publicKey, privateKey } = generateKeyPairSync('rsa', {
      modulusLength: 4096,  // the length of your key in bits
      publicKeyEncoding: {
        type: 'spki',       // recommended to be 'spki' by the Node.js docs
        format: 'pem'
      },
      privateKeyEncoding: {
        type: 'pkcs8',      // recommended to be 'pkcs8' by the Node.js docs
        format: 'pem',
        cipher: 'aes-256-cbc',   // *optional*
        passphrase: 'top secret' // *optional*
      }
    });
    
        2
  •  1
  •   Josh Peak    7 年前

    这里的问题是DH密钥不是RSA密钥,并且不完全兼容。

    不幸的是,node不能通过 crypto 模块或者有点令人失望。你需要和当地人交流 openssl 库执行此操作,或根据您的要求使用第三方模块。

    keypair 是一个简单的库,可以在给定的情况下工作

    const keypair = require('keypair');
    const keys: { private: string, public: string } = keypair({ bits : 2056 }); // 2056 is the default but added for example
    

    openpgpjs 它的特点更多,同时也专注于成为一个平台不可知的模块。如果您希望在浏览器和节点中进行加密,那么这可能是一个不错的选择。

    推荐文章