我正在研究RSA密码系统。公钥由$(n,e)$,模数(两个大质数的乘积)和加密指数组成。我想将模数$ n $和指数$ e $分开。典型的公共密钥用base64表示,具有以下类型:现在,根据上述密钥,尚不清楚哪个部分是模数,哪个是模数。是指数。如何提取两者?

评论

脱离主题,但极其方便:将其粘贴到https://lapo.it/asn1js/,然后根据常识或文档阅读和解释。这适用于其他实际问题。

#1 楼

RSA密钥格式至少在RFC 3447和RFC 5280中定义。该格式基于ASN.1,并且不仅包含原始模数和指数。

如果解码以64为基数的ASN解码。 1,您会发现一些包装(如对象标识符)以及内部ASN.1位串,其解码为:

(
    119445732379544598056145200053932732877863846799652384989588303737527328743970559883211146487286317168142202446955508902936035124709397221178664495721428029984726868375359168203283442617134197706515425366188396513684446494070223079865755643116690165578452542158755074958452695530623055205290232290667934914919, 
    65537
)


前者是2048-位模$ n $,后者是公共指数$ e $,通常选择3或65537,例如此处选择65537。要对任意密钥进行相同操作,您至少需要读ASN.1。 ,或者使用现有的解码器。

#2 楼

我想帮助您确切地分解您所看到的。

如果你把你的base64字符串:


MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqGKukO1De7zhZj6 + H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ / DgYSF6vUpwmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1 / 3J + skZ6UtW + 5u09lHNsj6tQ51s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQAB


然后将其解码为十六进制:

30 81 9F 30 0D 06 09 2A  86 48 86 F7 0D 01 01 01
05 00 03 81 8D 00 30 81  89 02 81 81 00 AA 18 AB
A4 3B 50 DE EF 38 59 8F  AF 87 D2 AB 63 4E 45 71
C1 30 A9 BC A7 B8 78 26  74 14 FA AB 8B 47 1B D8
96 5F 5C 9F C3 81 84 85  EA F5 29 C2 62 46 F3 05
50 64 A8 DE 19 C8 C3 38  BE 54 96 CB AE B0 59 DC
0B 35 81 43 B4 4A 35 44  9E B2 64 11 31 21 A4 55
BD 7F DE 3F AC 91 9E 94  B5 6F B9 BB 4F 65 1C DB
23 EA D4 39 D6 CD 52 3E  B0 81 91 E7 5B 35 FD 13
A7 41 9B 30 90 F2 47 87  BD 4F 4E 19 67 02 03 01
00 01 


所以问题是:这是什么?好吧,它实际上是ASN.1编码的DER变体。 ASN.1是一个可怕的怪物,但是您可以使用基于Web的ASN.1解码器来发现这些值实际上是这样的:

30 81 9F             ;30=SEQUENCE (0x9F = 159 bytes)
|  30 0D             ;30=SEQUENCE (0x0D = 13 bytes)
|  |  06 09          ;06=OBJECT_IDENTIFIER (0x09 = 9 bytes)
|  |  2A 86 48 86    ;Hex encoding of 1.2.840.113549.1.1
|  |  F7 0D 01 01 01
|  |  05 00          ;05=NULL (0 bytes)
|  03 81 8D 00       ;03=BIT STRING (0x8d = 141 bytes)
|  |  30 81 89       ;30=SEQUENCE (0x89 = 137 bytes)
|  |  |  02 81 81    ;02=INTEGER (0x81 = 129 bytes) the modulus
|  |  |  00          ;leading zero of INTEGER 
|  |  |  AA 18 AB A4 3B 50 DE EF  38 59 8F AF 87 D2 AB 63 
|  |  |  4E 45 71 C1 30 A9 BC A7  B8 78 26 74 14 FA AB 8B 
|  |  |  47 1B D8 96 5F 5C 9F C3  81 84 85 EA F5 29 C2 62 
|  |  |  46 F3 05 50 64 A8 DE 19  C8 C3 38 BE 54 96 CB AE 
|  |  |  B0 59 DC 0B 35 81 43 B4  4A 35 44 9E B2 64 11 31 
|  |  |  21 A4 55 BD 7F DE 3F AC  91 9E 94 B5 6F B9 BB 4F 
|  |  |  65 1C DB 23 EA D4 39 D6  CD 52 3E B0 81 91 E7 5B 
|  |  |  35 FD 13 A7 41 9B 30 90  F2 47 87 BD 4F 4E 19 67 
|  |  02 03          ;02=INTEGER (0x03 = 3 bytes) - the exponent
|  |  |  01 00 01    ;hex for 65537


是十六进制的两个重要数字:



指数:65537(几乎每个人都普遍使用65,537作为其主要指数)


模数:00 AA 18 AB A4 3B 50 DE EF 38 59 8F AF 87 D2 AB 63 4E 45 71 C1 30 A9 BC A7 B8 78 26 74 14 FA AB 8B 47 1B D8 96 5F 5C 9F C3 81 84 85 EA F5 29 C2 62 46 F3 05 50 64 A8 DE 19 C8 C3 38 BE 54 96 CB AE B0 59 DC 0B 35 81 43 B4 4A 35 44 9E B2 64 11 31 21 A4 55 BD 7F DE 3F AC 91 9E 94 B5 6F B9 BB 4F 65 1C DB 23 EA D4 39 D6 CD 52 3E B0 81 91 E7 5B 35 FD 13 A7 41 9B 30 90 F2 47 87 BD 4F 4E 19 67


或者,在十进制,你的模量:




没有/>需要OpenSSL及其voodoo命令。

评论


$ \ begingroup $
实际上OID的DER / BER编码不是'hex',它是带有'more'标志的7位块,除了前两个弧是特殊的。就是说,周围有许多工具可以对其进行编码/解码,因此您无需手动进行。还要注意,通常选择$ e $作为质数,包括65537,但是RSA仅要求将其与Carmichael($ n $)互质。
$ \ endgroup $
–dave_thompson_085
16 Jun 15'12:29



$ \ begingroup $
@ dave_thompson_085您将看到OID的十六进制编码。我知道没有工具可以将OID转换为十六进制(即8位二进制)
$ \ endgroup $
–伊恩·博伊德(Ian Boyd)
16 Jun 15'13:33



$ \ begingroup $
@IanBoyd对DER变体的很好解释。
$ \ endgroup $
–卡达
17年5月9日在11:13

$ \ begingroup $
DER的绝佳解释。
$ \ endgroup $
–姚景国
18年4月6日在9:25

$ \ begingroup $
@IanBoyd:FWIW这是一个这样的工具。
$ \ endgroup $
–psmears
20年7月16日在14:15

#3 楼

在实践中,可以使用openssl提取信息:

$ cat pubkey.txt
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0
FPqri0cb2JZfXJ/DgYSF6vUpwmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/
3j+skZ6UtW+5u09lHNsj6tQ51s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQAB
-----END PUBLIC KEY-----

$ openssl rsa -pubin -in pubkey.txt -text -noout
Public-Key: (1024 bit)
Modulus:
    00:aa:18:ab:a4:3b:50:de:ef:38:59:8f:af:87:d2:
    ab:63:4e:45:71:c1:30:a9:bc:a7:b8:78:26:74:14:
    fa:ab:8b:47:1b:d8:96:5f:5c:9f:c3:81:84:85:ea:
    f5:29:c2:62:46:f3:05:50:64:a8:de:19:c8:c3:38:
    be:54:96:cb:ae:b0:59:dc:0b:35:81:43:b4:4a:35:
    44:9e:b2:64:11:31:21:a4:55:bd:7f:de:3f:ac:91:
    9e:94:b5:6f:b9:bb:4f:65:1c:db:23:ea:d4:39:d6:
    cd:52:3e:b0:81:91:e7:5b:35:fd:13:a7:41:9b:30:
    90:f2:47:87:bd:4f:4e:19:67
Exponent: 65537 (0x10001)


模数以十六进制打印,如何获得其十进制值留给读者练习。

#4 楼

您可以直接使用-modulus命令的参数openssl rsa


echo '-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0 FPqri0cb2JZfXJ/DgYSF6vUpwmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/ 3j+skZ6UtW+5u09lHNsj6tQ51s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQAB -----END PUBLIC KEY-----' | openssl rsa -pubin -modulus -noout

模/> = AA18ABA43B50DEEF38598FAF87D2AB634E4571C130A9BCA7B878267414FAAB8B471BD8965F5C9FC3818485EAF529C26246F3055064A8DE19C8C338BE5496CBAEB059DC0B358143B44A35449EB264113121A455BD7FDE3FAC919E94B56FB9BB4F651CDB23EAD439D6CD523EB08191E75B35FD13A7419B3090F24787BD4F4E1967


#5 楼

您可以使用openssl asn1parse检查任何ASN.1结构。在您的情况下

$ openssl asn1parse -i -dump -in cse-18031
 0:d=0  hl=3 l= 159 cons: SEQUENCE
 3:d=1  hl=2 l=  13 cons:  SEQUENCE
 5:d=2  hl=2 l=   9 prim:   OBJECT            :rsaEncryption
16:d=2  hl=2 l=   0 prim:   NULL
18:d=1  hl=3 l= 141 prim:  BIT STRING
   0000 - 00 30 81 89 02 81 81 00-aa 18 ab a4 3b 50 de ef   .0..........;P..
   0010 - 38 59 8f af 87 d2 ab 63-4e 45 71 c1 30 a9 bc a7   8Y.....cNEq.0...
   0020 - b8 78 26 74 14 fa ab 8b-47 1b d8 96 5f 5c 9f c3   .x&t....G..._\..
   0030 - 81 84 85 ea f5 29 c2 62-46 f3 05 50 64 a8 de 19   .....).bF..Pd...
   0040 - c8 c3 38 be 54 96 cb ae-b0 59 dc 0b 35 81 43 b4   ..8.T....Y..5.C.
   0050 - 4a 35 44 9e b2 64 11 31-21 a4 55 bd 7f de 3f ac   J5D..d.1!.U...?.
   0060 - 91 9e 94 b5 6f b9 bb 4f-65 1c db 23 ea d4 39 d6   ....o..Oe..#..9.
   0070 - cd 52 3e b0 81 91 e7 5b-35 fd 13 a7 41 9b 30 90   .R>....[5...A.0.
   0080 - f2 47 87 bd 4f 4e 19 67-02 03 01 00 01            .G..ON.g.....


输出是键类型和位字符串。令人失望,我知道。但无需担心。 ASN.1结构喜欢包含其他标为位字符串的ASN.1结构。我们只需要注意行上第一个数字“ bit string”,它就是偏移量并再次运行asn1parse。

$ openssl asn1parse -i -dump -in cse-18031 -strparse 18
  0:d=0  hl=3 l= 137 cons: SEQUENCE
  3:d=1  hl=3 l= 129 prim:  INTEGER           :AA18ABA43B50DEEF38598FAF87D2AB634E4571C130A9BCA7B878267414FAAB8B471BD8965F5C9FC3818485EAF529C26246F3055064A8DE19C8C338BE5496CBAEB059DC0B358143B44A35449EB264113121A455BD7FDE3FAC919E94B56FB9BB4F651CDB23EAD439D6CD523EB08191E75B35FD13A7419B3090F24787BD4F4E1967
135:d=1  hl=2 l=   3 prim:  INTEGER           :010001


输出两个简单的序列整数。显而易见,哪个是模数,哪个是指数。

您实际上可以对所遇到的任何asn.1使用相同的工作流程。所有标识符都是全局分配的,没有可追踪的“代码页”。

评论


$ \ begingroup $
例如,您可以在openssl中查看和使用Microsoft的x509扩展而无需任何支持:superuser.com/questions/615832/…
$ \ endgroup $
–user185953
19年9月5日在9:05