当前位置:   article > 正文

从PKCS#1格式RSA公钥提取模数(modulus)和指数(exponent)_公钥tlv拆解

公钥tlv拆解

从PKCS#1格式RSA公钥提取模数(modulus)和指数(exponent)

PKCS#1格式rsa公钥的pem文件内容:

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApuT2wKtxEj1kr7CHj3GT
eeg1JIaSfiM8hzGvc3ntd84MCF0U/SnLOAVZ3C8J+2mfymBy7Zc83sC7+dc0KzuF
jWI47QQHiafh+8YNbljgjXMWLJgiovkQxBrJ7nbfMGIol3QEijKL19Sp+yYKfE4+
Fnu8g89dQUhc7pJGNGaN4nLOZtV/bdPLXBXmUIjOBskdTTwYnIiMvSlXwHuYxXHE
qZMs14t22TUAGyBMglx2bnXIh+9wDr3hz4vcaklqFtlpys5tUKVqbvOLq6LBEduL
yOCIPSt24d2oFnfuD7W4EuhfWBa8Z9dZpPqUBGQ4SBb/vq6Ycmrj7/B6iz32Qq+6
hwIDAQAB
-----END PUBLIC KEY-----
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

除去-----BEGIN PUBLIC KEY----------END PUBLIC KEY-----两行内容,中间部分为base64编码的数据。首先通过base64解码获取十六进制数据。复制这部分数据到
此网站进行base64解码,得到十六进制数据如下:

30 82 01 22 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 00 03 82 01 0f 00 30 82 01 0a 02 82 01 01 00 a6 e4 f6 c0 ab 71 12 3d 64 af b0 87 8f 71 93 79 e8 35 24 86 92 7e 23 3c 87 31 af 73 79 ed 77 ce 0c 08 5d 14 fd 29 cb 38 05 59 dc 2f 09 fb 69 9f ca 60 72 ed 97 3c de c0 bb f9 d7 34 2b 3b 85 8d 62 38 ed 04 07 89 a7 e1 fb c6 0d 6e 58 e0 8d 73 16 2c 98 22 a2 f9 10 c4 1a c9 ee 76 df 30 62 28 97 74 04 8a 32 8b d7 d4 a9 fb 26 0a 7c 4e 3e 16 7b bc 83 cf 5d 41 48 5c ee 92 46 34 66 8d e2 72 ce 66 d5 7f 6d d3 cb 5c 15 e6 50 88 ce 06 c9 1d 4d 3c 18 9c 88 8c bd 29 57 c0 7b 98 c5 71 c4 a9 93 2c d7 8b 76 d9 35 00 1b 20 4c 82 5c 76 6e 75 c8 87 ef 70 0e bd e1 cf 8b dc 6a 49 6a 16 d9 69 ca ce 6d 50 a5 6a 6e f3 8b ab a2 c1 11 db 8b c8 e0 88 3d 2b 76 e1 dd a8 16 77 ee 0f b5 b8 12 e8 5f 58 16 bc 67 d7 59 a4 fa 94 04 64 38 48 16 ff be ae 98 72 6a e3 ef f0 7a 8b 3d f6 42 af ba 87 02 03 01 00 01
  • 1

接下来对这十六进制数据进行解析。
这些十六进制数据使用的事TLV编码模式,即tag,length,value的模式对数据进行描述。

  • tag

tag一般占一个byte,表示一段数据的开始。常见的如0x30(SEQUENCE)0x02(INTEGER)0x03(BIT STRING)等,详细见下表

TypeASN.1 classEncodeing formTag value
BIT STRINGUNIVERSALPrimitive00000011(0x03)
BOOLEANUNIVERSALPrimitive00000001(0x01)
INTEGERUNIVERSALPrimitive00000010(0x02)
NULLUNIVERSALPrimitive00000101(0x05)
OBJECTIDENTIFIERUNIVERSALPrimitive
OCTET STRINGUNIVERSALPrimitive00000100(0x04)
BMPStringUNIVERSALPrimitive00011110(0x1E)
IA5StringUNIVERSALPrimitive00010110(0x16)
PrintableStringUNIVERSALPrimitive00010011(0x13)
TeletexStringUNIVERSALPrimitive00010100(0x14)
UTF8StringUNIVERSALPrimitive00001100(0x0C)
SEQUENCEUNIVERSALConstructed00110000(0x30)
SEQUENCE OFUNIVERSALConstructed00110000(0x30)
SETUNIVERSALConstructed00110001(0x31)
SET OFUNIVERSAConstructed00110001(0x31)

Encoded Tag Bytes

  • length

length为紧接着tag字节后面的一个字节,表示数据的长度,根据length字节的内容,可以分为两种形式,不同的形式有不同的数值。

  1. 短模式

当length字节的最高位为0时为短模式,长度的值为length字节本身数值,即低7位所表示的数据大小。

e.g.
0x09 : (0000 1001) 数据长度为9byte
0x71 :(0111 0001)数据长度为113byte

  1. 长模式

当length字节的最高位为1时为长模式,此时length字节中保存的不是数据的大小。真正表示数据大小的值是紧跟在length字节的后面若干个字节。而length字节低7位表示的则是这若干个字节的长度。

e.g.
0x82 0x01 0x22 0x30 0x0d 0x06 … :
假设0x82为length字节。0x82为1000 0010,由于最高位为1,说明在这里使用的是长模式。即低7位指示了紧接在其后的多少个字节标识了数据的长度。在这个例子中,低7位为000 0010,即2,因此紧接在0x82后面的0x01 0x22即为数据的长度。即数据长度为290个字节。

  • value

数据一般占若干个字节(也可能为0个字节,根据length决定),其长度有length指定。其中,如果tag为BIT STRING(0x03)时,第一个字节表示数据的最后一个字节有多少个位是没有被使用的(即无效的)。

e.g.
0x00 0x11 0x22 …
这个例子中,第一个字节为0x00,表示数据的最后一个字节没有被使用的位数为0,即所有位均有效。

分析流程

对本文的rsa公钥十六进制数据分析结果如下 :


30 ---> SEQUENCE (tag)
82 01 22 ---> 长模式, 数据长度由 01 22 表示,即290bytes(length)
    30 ---> SEQUENCE (tag)
    0d ---> 短模式,长度为0x0d个字节,即13bytes (length)
        06 ---> OBJECT IDENTIFIER (tag)
        09 ---> 短模式,长度为0x09个字节,即9bytes (length)
            2a 86 48 86 f7 0d 01 01 01 ---> OBJECT IDENTIFIER 的数据内容 (value)
    05 ---> NULL (tag)
    00 ---> 短模式,长度为0x00字节(length)
    03 ---> BIT STRING (tag)
    82 01 0f ---> 长模式,数据长度有 01 0f 表示,即271bytes (length)
        00 ---> 本数据最后一个字节没有无效位,即全部有效。
        30 ---> SEQUENCE (tag)
        82 01 0a ---> 长模式,数据长度有 01 0a 表示,即266bytes (length)
            02 ---> INTEGER 表示一个整数 (tag)
            82 01 01 ---> 长模式,数据长度有 01 01 表示,即257bytes (length)
                 00  a6 e4 f6 ... af ba 87 --->整型数,此处为模数,modulus (value)
            02 ---> INTEGER 表示一个整数 (tag)
            03 ---> 短模式,长度为0x03个字节,即3bytes (length)
                01 00 01 ---> 整型数,此处为指数,exponents (value)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

在公钥中,一般直接找到第一个0x02,即第一个整型数tag(INTEGER)即为modulus的TLV,第二个0x02为公钥指数的TLV。如果不幸某些数据中也包含了0x02,就只能逐个逐个地推导了。

参考 :
A Layman’s Guide to a Subset of ASN.1, BER, and DER
RSA modulus and exponent from public key
Encoded Tag Bytes

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/440296
推荐阅读
相关标签
  

闽ICP备14008679号