【问题标题】:Generate RSA key-pair from "N", "E", "D" keys using crypto module使用加密模块从“N”、“E”、“D”密钥生成 RSA 密钥对
【发布时间】:2020-02-26 09:27:48
【问题描述】:

我是密码学新手。

我正在使用 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" 密钥,以便其他应用程序可以加密和解密消息。如果在没有任何 3rd-party 库的情况下仅使用本机 NodeJS 加密模块就可以做到这一点,那就太好了。

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

【问题讨论】:

    标签: node.js cryptography rsa


    【解决方案1】:

    这工作正常,但我需要提取“n”、“e”、“d”密钥,以便其他应用程序可以加密和解密消息。如果没有任何第三方库,只有本机 NodeJS 加密模块,这将是可能的。

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

    顾名思义,私钥实际上不应该被共享。毕竟没有共享私钥这样的东西。密钥是为一个特定实体生成的,并且通常保存在生成​​它们的地方(可能不包括加密备份)。

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

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

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

    【讨论】:

    • 如何定义组件(n、e、d)来生成新的 RSA 公钥和私钥?你能举个例子吗,我从来没有真正使用过加密模块。另一个应用程序也使用 pkcs1,如果我使用 spki,他们仍然能够加密和解密消息吗?
    • 好吧,如果它查找 PKCS#1 并找到 SPKI,那么不,它不会工作。但是,PKCS#1 公钥是 SPKI 的一部分,因此当然可以使其工作。如果有标准化的方式来表示包含您可能需要的所有组件的键,您为什么如此迫切地提取单独的组件?
    • 我拥有所有组件(n、e、d),但最终我需要能够加密和解密来自使用相同组件的其他应用程序的消息。
    • 它的工作方式是:我将使用 rsa 加密的 diffiehellman prime 和生成器发送到另一个应用程序。然后另一个应用程序解密消息并生成 diffiehellman 密钥并将它们发送回给我。然后我生成共享的 diffiehellman 密钥并将它们发送回另一个应用程序。所有消息都使用 rsa 加密。所以我需要能够使用组件(n,e,d)加密/解密消息。我基本上是想握手。我认为某处也包含 rc4,但我不知道这是在哪里发生的。我对所有这些密码学都很陌生
    • 你完全不知道你在做什么,对吧?这根本不是 DH 的工作方式。您将签名的参数(可能包括公钥)发送给另一个站点,由后者验证参数并执行密钥协商。你在两边都这样做。正如我所料,这基本上是一个 XY 问题。重新思考,重新开始。
    【解决方案2】:

    您可以使用库 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: '...'
    }
    
    

    【讨论】:

      猜你喜欢
      • 2021-11-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-07
      • 1970-01-01
      • 2011-01-07
      • 1970-01-01
      相关资源
      最近更新 更多