当前位置: 首页 > 知识库问答 >
问题:

如何将JWK转换为PEM

姚麒
2023-03-14

这个问题更通用,而不是针对特定的语言,所以我将解释我的问题以及我在伪代码中尝试的内容。

我正在尝试从JWK集生成PEM公钥。JWK包括“e”(指数)和“n”(模量)变量。我的问题是,在不使用任何库和OpenSSL命令行工具的情况下,将此JWK转换为PEM的确切步骤是什么。

以下是供参考的 JWK:

{
  "kty": "RSA",
  "alg": "RS512",
  "kid": "26887d3ee3293c526c0e6dd05f122df53aa3f13d7dad06d25e266fa6f51db79fb52422aaf79f121476237e98dcd6640350fee47fec70e783544ec9a36e4605bc",
  "use": "sig",
  "n": "14m79mVwIE0JxQdKrgXVf7dVcBS90U0TvG7Yf7dG4NJocz1PNUrKrzGhe_FryOe0JahL_sjA2_rKw7NBCpuVx_zSPFRw6kqjewGicjXGus5Fmlf3zDuqwV4BWIFHyQexMPOly0agFfcM0M0MgBULXjINgBs9MwnRv7JVfRoGqXHsNM45djFDd3o4liu4LPlge_DquZUFLNu-BYAyAlWkz0H2TepZhGrN9VEPmxzQkNzXc1R4MpZvbxrRRgaAA2z094ik3hk86JhfyFq-LDcueZhtshmrYZ95LWgMlQ7PixkeK1HkeEYMt20lmNzR8B8KabimYmibxA4Ay9gpRwfp-Q",
  "e": "AQAB"
}

我的大部分研究来源于节点jwk到pem库(可以在这里找到:https://github.com/Brightspace/node-jwk-to-pem)以及使用PHP中的JOSE库的StackOverflow问题(可以在这里找到:如何将公钥从JWK转换为OpenSSL的PEM?)

根据我通过阅读上述库(以及其他一些没有完全提及分步过程的文章和问题)得出的结论,我发现第一步是将模数和指数转换为整数(特别是 BigInt)。这通常会导致以下结果:

n = 27209154847141595039206198313134388207882403216639061643382959557246344691110642716248339592972939239825436848454712213431917464875221502188500634554426063986720722251339335488215426908010590565758292169712942346285217861588132983738839891250753593240057639347814778952277719613395670962156961452389927728643840215833830614315091417876959205843957512422401240879135352731575182574836052718961865690645602829768565458494497550672252951063585023601307115444743487394113997186698238507983094748342588645472362960665610355698438390751920697759620235642103374737421940385132232531739910444003185620313592808726865629407737
e = 65537

使用这些信息,我如何从指数和模数生成PEM公钥?任何伪代码或建议都是难以置信的!

共有1个答案

万俟宜修
2023-03-14

RSA公钥由模n和指数e

您可以使用< code>n和< code>e字段直接从类型为< code>RSA的JWK获取该信息:

“n”(模数)参数包含RSA公钥的模数值。它表示为Base64urlUInt编码值。

“e”(指数)参数包含RSA公钥的指数值。它表示为Base64urlUInt编码的值。

要创建表示此公钥信息的PEM文件,基本上需要构建其等效ASN。1 DER编码表示,可能带有一些前导码。在其原始形式中,它在RFC3447中定义如下:

RSAPublicKey ::= SEQUENCE {
  modulus           INTEGER,  -- n
  publicExponent    INTEGER   -- e
}

ASN.1定义了表示任意数据结构的规则和类型,并且为此目的在密码学中广泛使用。

ASN.1仅为您提供了语法,但该信息的实际编码是使用不同的编码格式执行的,尤其是DER。

执行编码的方式并不简单:Let's Encrypt提供了一篇关于这个主题的优秀文章。伟大的lapo.it/asn1js网站也为检查ASN.1 DER编码信息提供了一个极好的工具。

例如,考虑以下模数和指数,从下面提到的 SO 问题中提取:

SEQUENCE (2 elements)
   INTEGER (2048 bit): EB506399F5C612F5A67A09C1192B92FAB53DB28520D859CE0EF6B7D83D40AA1C1DCE2C0720D15A0F531595CAD81BA5D129F91CC6769719F1435872C4BCD0521150A0263B470066489B918BFCA03CE8A0E9FC2C0314C4B096EA30717C03C28CA29E678E63D78ACA1E9A63BDB1261EE7A0B041AB53746D68B57B68BEF37B71382838C95DA8557841A3CA58109F0B4F77A5E929B1A25DC2D6814C55DC0F81CD2F4E5DB95EE70C706FC02C4FCA358EA9A82D8043A47611195580F89458E3DAB5592DEFE06CDE1E516A6C61ED78C13977AE9660A9192CA75CD72967FD3AFAFA1F1A2FF6325A5064D847028F1E6B2329E8572F36E708A549DDA355FC74A32FDD8DBA65
   INTEGER (24 bit): 010001

相应的ASN.1 DER编码如下:

30 82 01 0A      ;sequence (0x10A bytes long)
   02 82 01 01   ;integer (0x101 bytes long)
      00 EB506399F5C612F5A67A09C1192B92FAB53DB28520D859CE0EF6B7D83D40AA1C1DCE2C0720D15A0F531595CAD81BA5D129F91CC6769719F1435872C4BCD0521150A0263B470066489B918BFCA03CE8A0E9FC2C0314C4B096EA30717C03C28CA29E678E63D78ACA1E9A63BDB1261EE7A0B041AB53746D68B57B68BEF37B71382838C95DA8557841A3CA58109F0B4F77A5E929B1A25DC2D6814C55DC0F81CD2F4E5DB95EE70C706FC02C4FCA358EA9A82D8043A47611195580F89458E3DAB5592DEFE06CDE1E516A6C61ED78C13977AE9660A9192CA75CD72967FD3AFAFA1F1A2FF6325A5064D847028F1E6B2329E8572F36E708A549DDA355FC74A32FDD8DBA65
   02 03         ;integer (3 bytes long)
      010001

在ASN中。1 DER,每个元素都被编码为类型长度值三元组。

类型由标签标识,通常用一个字节编码。

例如,30表示SEQUENCE,而02对应于INTEGER类型。

上面提到的文章提供了ASN.1定义的不同类型的列表以及相应的标签

长度有点棘手:如果关联值最多为1270x7F)字节长,则用单个字节表示。如果字节数大于127,那么这个第一个长度字节指定了实际定义长度的字节数。请考虑阅读本文的长度部分,我认为它很有说明性。

然后,包括实际值。

在提供的示例中,30 82 01 0A表示:

    < li> 30:一个< code >序列。 < li> 82:长度字节。<代码> 0x82

现在,值<code>02 82 01 01 00 EB506399F5C612F5A67A09C119…</code>:

    < li> 02:一个< code >整数 < li> 82:长度字节。同样,< code>0x82

最后,02 03 010001

  • 02:一个整数
  • 03:指数值为3字节长
  • 010001:指数值

然后,该结果应编码为base64,并包含在特殊的文本分隔符中,例如-----BEGIN RSA PUBLIC KEY----------END RSA PUBLIC KEY----

请注意,您有几种选择来表示PEM格式的密钥,上面描述的一种,PKCS#1,以及更通用的X.509,适用于表示不同格式的密钥(形式为< code> - BEGIN PUBLIC KEY - )。考虑阅读这个精彩的SO问题和相关回答,它不仅详细解释了RSA公钥基础知识,还解释了这些不同表示的注意事项。

也考虑阅读这个问题,尤其是这个其他的问题,我认为它们也会有所帮助。

 类似资料:
  • 我已经购买了SSL证书,并且从供应商那里收到了证书和作为私钥的. pem文件?现在我需要将此. pem密钥转换为bitnami Redmine Apache Web服务器的. key以使其正常工作。 我该怎么做?什么程序或命令来做?就使用Openssl等实现这一点而言,我是个新手。 任何建议将不胜感激! 谢谢你。

  • 问题内容: 我在mySQL 5.1中有一个数据类型的日期列。如何将其转换为DATE? 这是我到目前为止所拥有的- 得到这个 错误-#1064-您的SQL语法有错误;查看与您的MySQL服务器版本相对应的手册以获取正确的语法,以在’FROM 7 FOR 4附近使用) 请帮忙。 问题答案: 您可以使用MySQL的功能 尽管我怀疑您使用Unix时间戳会更轻松

  • 问题内容: 有没有一种简单的方法可以避免处理文本编码问题? 问题答案: 您确实无法避免处理文本编码问题,但是Apache Commons中已有一些解决方案: 至: 至: 您只需要选择所需的编码即可。

  • 问题内容: 如何使用Java将Dicom文件(.dcm)转换为jpeg图像?这是我的代码: 我在运行项目时遇到以下错误 请帮助并提前感谢 问题答案: 这是使用dcm4che 2将DICOM转换为JPEG的链接 以下是我的代码,效果很好,我将其与导入一起放置,因此可能用完了。 用于运行它的罐子 dcm4che-imageio-2.0.28.jar dcm4che-image-2.0.28.jar j

  • 问题内容: 我正在使用A 将Json从Web转换为字符串。 这可能很简单,但是我似乎无法将此字符串转换为。 我怎样才能做到这一点? 问题答案: 请参阅文档和示例。

  • 问题内容: 如何在Java中将org.jdom.Document转换为字符串? 问题答案: