使用加密模块从“ N”,“ E”,“ D”密钥生成RSA密钥对

时间:2020-02-26 09:27:48

标签: node.js cryptography rsa

我是密码学的新手。

我正在使用crypto.generateKeyPairSync()

创建RSA密钥对。
const crypto = require('crypto')

const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', {
  modulusLength: 2048,
  publicExponent: 3,
  publicKeyEncoding: {
    type: 'pkcs1',
    format: 'pem'
  },
  privateKeyEncoding: {
    type: 'pkcs1',
    format: 'pem'
  }
})

console.log(publicKey)
console.log(privateKey)

// print "n", "e", "d" keys

这很好用,但是我需要提取"n", "e", "d"密钥,以便其他应用程序可以加密和解密消息。如果没有任何第3方库,而仅使用本机NodeJS加密模块,这将是很好的。

如果无法提取"n", "e", "d"密钥,是否可以使用其他应用程序中现有的"n", "e", "d"密钥来创建新的公钥和私钥?

2 个答案:

答案 0 :(得分:0)

这很好用,但是我需要提取“ n”,“ e”,“ d”键,以便其他应用程序可以加密和解密消息。如果没有任何第三方库,而只有原生NodeJS加密模块,这将是很好的选择。

首先,模数n,公共指数e和私有指数d不是密钥,它们是用于构成密钥的组件。由于RSA密钥至少包含 两个组件,因此您需要某种方法将它们彼此区分开。您需要某种将各个组件分开的数据结构,这正是PKCS#1 ASN.1规范所提供的。仅指定您将使用PEM格式的PKCS#1交付RSA密钥就足够了。

顾名思义,私钥实际上不应共享。毕竟没有共享私钥之类的东西。密钥是为一个特定实体生成的,通常保存在生成​​它们的位置(可能免除加密备份)。

如果仅使用n和d,则可能会遗漏任何为私钥生成的CRT参数,这意味着在最佳情况下RSA密钥操作不会运行。在最坏的情况下,RSA实施非常挑剔,根本无法运行。

最后,正如文档正确指出的那样,您应该使用'spki'作为输出格式(在X.509标准中指定的证书中使用的公钥,称为SubjectPublicKeyIdentifier)和{ {1}},因为其中包含所用键类型的指示。这些可能比PKCS#1更好地受到其他应用程序的支持。

如果他们自己不能解码,则只需将base 64复制到this site (online ASN.1 decoder)并复制相关值。您可以在PKCS#1 standard中找到(对于'pkcs8')的值的顺序。

答案 1 :(得分:0)

您可以使用库pem-jwk来提取公钥/私钥的组件,如下所示:

const pem2jwk = require('pem-jwk').pem2jwk

console.log(pem2jwk(pemPublicKey));
OUTPUT:
{
  kty: '...',
  n: '...',
  e: '...'
}

console.log(pem2jwk(pemPrivateKey));
OUTPUT:
{
  kty: '...',
  n: '...',
  e: '...',
  d: '...',
  p: '...',
  q: '...',
  dp: '...',
  dq: '...',
  qi: '...'
}