这个问题是更通用的,而不是特定的语言,所以我将解释我的问题和我用伪代码尝试了什么。
我正在尝试从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)和StackOverflow问题(在PHP中使用JOSE库(在这里可以找到:如何将OpenSSL的公钥从JWK转换为PEM?) )。
通过阅读上面提到的库(再加上其他几篇文章和问题,没有提到逐步的过程),我发现第一步是将模数和指数转换为整数(特别是BigInt)。这通常导致以下情况:
n = 27209154847141595039206198313134388207882403216639061643382959557246344691110642716248339592972939239825436848454712213431917464875221502188500634554426063986720722251339335488215426908010590565758292169712942346285217861588132983738839891250753593240057639347814778952277719613395670962156961452389927728643840215833830614315091417876959205843957512422401240879135352731575182574836052718961865690645602829768565458494497550672252951063585023601307115444743487394113997186698238507983094748342588645472362960665610355698438390751920697759620235642103374737421940385132232531739910444003185620313592808726865629407737
e = 65537利用这些信息,我将如何从指数和模数生成PEM公钥?任何伪代码或建议都会令人难以置信!
发布于 2022-02-12 22:34:03
RSA公钥是由模n和指数e定义的。
您可以使用RSA和e字段直接从e获取该信息:
"n“(模数)参数包含RSA公钥的模值。它表示为Base64urlUInt编码的值。"e“(指数)参数包含RSA公钥的指数值。它表示为Base64urlUInt编码的值。
要创建一个表示此公钥信息的PEM文件,您基本上需要构建其等效的ASN.1 DER编码表示形式,可能需要有一些前导。在其原始形式中,它在RFC3447中的定义如下
RSAPublicKey ::= SEQUENCE {
modulus INTEGER, -- n
publicExponent INTEGER -- e
}ASN.1定义了用于表示任意数据结构的规则和类型,并在密码学中被广泛用于此目的。
ASN.1只给出一个语法,但是实际的信息编码是使用不同的编码格式执行的,特别是DER。
编码的执行方式是非常重要的:让我们加密提供有关主题的一篇优秀文章。伟大的Apo.it/asn1js站点也为检查ASN.1编码信息提供了一个极好的工具。
例如,从下面提到的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定义的带有相应标记的不同类型的列表。
长度有点棘手:如果关联的值高达127 (0x7F)字节长,则由单个字节表示。如果字节数大于127,则第一个长度字节指定实际定义长度的字节数。请考虑阅读Length一节的这篇文章,我认为它是非常解释性的。
然后,将实际值包括在内。
在提供的示例中,30 82 01 0A意味着:
30:一个SEQUENCE。82:长度字节。0x82 & 0x7F -> 0x02实际值长度以2字节表示。01 0A:实际值长度,266字节长。现在,值02 82 01 01 00 EB506399F5C612F5A67A09C119...
02:一个INTEGER82:长度字节。再说一遍,0x82 & 0x7F -> 0x02。实际值长度以2字节表示。01 01:实际值长度,257字节长,模数2048位,加上第一个字节0x00 (参见上述条款中的Integer padding部分)。00 EB506399F5C612F5A67A09C119:填充模量值。最后,02 03 010001
02:一个INTEGER。03:指数值是3字节长。010001:指数值。然后,应该将结果编码为base64,并将其封装在特殊的文本分隔符中,例如,-----BEGIN RSA PUBLIC KEY-----和-----END RSA PUBLIC KEY-----。
请注意,您有几个选项可以表示PEM格式的键,上面描述的选项是PKCS#1,以及更通用的X.509,它们适合于以不同格式表示键(表单-----BEGIN PUBLIC KEY-----之一)。考虑阅读这个精彩的所以问题和相关的答案,它不仅非常详细地解释了RSA公钥的基本原理,而且还解释了这些不同表示的注意事项。
https://stackoverflow.com/questions/70974044
复制相似问题