首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NodeJS生成用于签名和验证消息的有效PEM密钥。

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

Stack Overflow用户
提问于 2018-08-21 06:30:04
回答 2查看 14.7K关注 0票数 16

上下文

摘自Node10.9.0(2018年8月)关于TLS/SSL的NodeJS文档。

概念

代码语言:javascript
复制
openssl genrsa -out ryans-key.pem 2048

将产生:

代码语言:javascript
复制
-----BEGIN RSA PRIVATE KEY-----
base64 encoded magic here...
-----END RSA PRIVATE KEY-----

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

签名

代码语言:javascript
复制
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'));

我尝试了以下几点,但没有成功:

代码语言:javascript
复制
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);

获取以下错误:

代码语言:javascript
复制
Error: error:0D07207B:asn1 encoding routines:ASN1_get_object:header too long
    at Sign.sign (internal/crypto/sig.js:84:26)
...

问题

如何使用NodeJS中的NodeJS库来实现openssl命令行工具正在执行的操作(或另一个NPM模块)来创建一个有效的openssl格式的公钥/私钥对,这是Sign类所需要的?

类似的未解决问题

解决方案

这是完成工作解决方案的起点,这要归功于来自被接受的答案JacobTDC,其中NodeJS v10.12.0添加了这个特性。

代码语言:javascript
复制
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'));
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-11-06 14:21:50

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

我从下面的Node.js文档中提供了一个示例(并添加了注释):

代码语言:javascript
复制
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*
  }
});
票数 23
EN

Stack Overflow用户

发布于 2018-08-21 16:47:28

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

不幸的是,节点无法通过crypto模块生成真正的RSA对,这有点令人失望。您需要与本地openssl库交互才能做到这一点,或者需要根据您的需求建立第三方模块。

就第三方模块而言,keypair是一个简单的库,可以在给定的情况下工作。

代码语言:javascript
复制
const keypair = require('keypair');
const keys: { private: string, public: string } = keypair({ bits : 2056 }); // 2056 is the default but added for example

我还发现了openpgpjs的好结果,它更有特色,同时也专注于作为一个平台不可知论的模块。如果您想在浏览器和节点中执行加密操作,那么这可能是一个很好的选择。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51942824

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档