NodeJS Generate Valid PEM keys for Signing and Verifying messages

十年热恋 提交于 2020-12-29 03:05:17

问题


Context

From the NodeJS documentation on TLS/SSL for Node v10.9.0 (2018-AUG)

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

openssl genrsa -out ryans-key.pem 2048

Will produce:

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

Which I can then successfully use the Sign class to cryptographically sign a message:

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

I have tried the following with no success:

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

Getting the following error:

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

The Question

How do I use the crypto library in NodeJS to achieve what openssl command line tool is performing (or another NPM module) to create a valid PEM formatted public/private key-pair which is required by the Sign class?

Similar unresolved questions

  • Generate Key for signing within nodejs

Solution

Here is the start to finish working solution thanks to the accepted answer from JacobTDC where NodeJS v10.12.0 added this feature.

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

回答1:


As of Node.js v10.12.0, you can use crypto.generateKeyPair and crypto.generateKeyPairSync.

I have provided an example from the Node.js docs below (with added comments):

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:


The problem here is DH keys are not RSA keys and not fully compatible.

Unfortunately, node does not have the ability to produce real RSA pairs via the crypto module either which is a bit disappointing. You'll need to either interact with your local openssl library to do this, or a third party module depending on your requirements.

As far as third party modules, keypair is a simple library which will work in your given situation

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

I've also found good results with openpgpjs which is much more featured while also focusing on being a platform agnostic module. If you're looking at doing crypto in the browser as well as node, then this might be a good option.



来源:https://stackoverflow.com/questions/51942824/nodejs-generate-valid-pem-keys-for-signing-and-verifying-messages

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!