RSA密钥格式说明

DER 是一个 TLV 编码,数据结构 SEQUENCE 是总的 TAG 且其 TAG=0x30。

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)

长度的表示方法有 2 种情况

数据长度 L < 0x80 的时候,Length 即为数据的长度;

数据长度 L >= 0x80 的时候,Length 为0x8x,表示后面跟的 x 标识 Length 所占字节长度。例如 82 01 20,0x82 表示 82 后面 2 个字节为长度的字节长度,数据长度为 0x0120。

TAG  0x02,其值的类型为整型。需要要注意的是当第一个数据字节的最高位为 1 时,即 0x8x 时,要在最高字节填充 0x00。这是因为 modulus 为一个大整数,最高位为符号位,其为1时,就是负数,所以要在最高位填充 0x00 以保证不为负。

如:

02 03 00 8C27      T=0x02 L=0x03 V=十进制 35879 (数据 0x8C 最高位为 1,数据前需要补 0x00)

02 03 00 8D9F      T=0x02 L=0x03 V=十进制 36255 (数据 0x8D 最高位为 1,数据前需要补 0x00)

02 02 4C6B      T=0x02 L=0x02 V=十进制 19563

如果tag为BIT STRING(0x03)时,第一个字节表示数据的最后一个字节有多少个位是没有被使用的(即无效的)。

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

 

RSA Public Key file (PKCS#1)

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

Public Key file (PKCS#8)

PublicKeyInfo ::= SEQUENCE {
    algorithm AlgorithmIdentifier,
    PublicKey BIT STRING                                  TAG:03
}
AlgorithmIdentifier ::= SEQUENCE {
    algorithm OBJECT IDENTIFIER,                                              TAG:06
    parameters ANY DEFINED BY algorithm OPTIONAL          TAG:05
}

RSA Private Key file (PKCS#1)

RSAPrivateKey ::= SEQUENCE {
    version Version,    Version 的 TAG 为 0x02,在 RSA 私钥的 DER 编码中,除了 SEQUENCE 的 TAG 为 0x30,其余的为 0x02,目前的 Version 值为 0。
    modulus INTEGER, -- n
    publicExponent INTEGER, -- e
    privateExponent INTEGER, -- d
    prime1 INTEGER, -- p
    prime2 INTEGER, -- q
    exponent1 INTEGER, -- d mod (p-1)
    exponent2 INTEGER, -- d mod (q-1)
    coefficient INTEGER, -- (inverse of q) mod p
    otherPrimeInfos OtherPrimeInfos OPTIONAL
}

Private Key file (PKCS#8)

The unencrypted PKCS#8 encoded data starts and ends with the tags:

PrivateKeyInfo ::= SEQUENCE {

    version Version,
    algorithm AlgorithmIdentifier,
    PrivateKey BIT STRING
}
AlgorithmIdentifier ::= SEQUENCE {
    algorithm OBJECT IDENTIFIER,
    parameters ANY DEFINED BY algorithm OPTIONAL
}
So for an RSA private key, the OID is 1.2.840.113549.1.1.1 and there is a RSAPrivateKey as the PrivateKey key data bitstring.

rsaPKCS#8公钥十六进制数据分析


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)

rsaPKCS#1公钥格式数据解析示例

3081B70281B1009EC4B25143BC031540BB8B5A75551D3C5516CC211CB9A41E6C60BF02A535116A22F2B7
ACBD7EFBABE1E54FBF0E3066CB235D2F6B487DBC98F64A27BF233A2F12FC63B2185BF60FC1A7C79C3A8
D596A2423616AFAC8EA7EA715BFFA5828902487861AF7436CF02D11FB5272D237D344652FFA13DD3B8626
5C5DA15C28C4F3061619DBF6FFA1107031AADA36DECD4A4D5E6DA09CADE2F761215C7C39C1213C66CE
C432E6DE6F230B4103634A50B3392BC5020103

数据按照 TLV 分解后:

30 81 B7

02 81 B1        -- 模值 n TAG=0x02,标识内容为 BIT 数据流,0x81 代表有一字节代表长度,数据长度 L=0xB1

去掉前面的 0x00,余下 176 字节是 rsa 公钥的 N 值(1408 bit),modulus 为一个大整数,最高位为符号位,其为 1 时,就是负数,所以要在最高位填充 0x00 以保证不为负。

MOD_V = 009EC4B25143BC031540BB8B5A75551D3C5516CC211CB9A41E6C60BF02A535116A22F2B7ACBD7EFBAB
E1E54FBF0E3066CB235D2F6B487DBC98F64A27BF233A2F12FC63B2185BF60FC1A7C79C3A8D596A24236
16AFAC8EA7EA715BFFA5828902487861AF7436CF02D11FB5272D237D344652FFA13DD3B86265C5DA15C
28C4F3061619DBF6FFA1107031AADA36DECD4A4D5E6DA09CADE2F761215C7C39C1213C66CEC432E6D
E6F230B4103634A50B3392BC5

 

02 01 03        -- 公开指数 e TAG=0x02 L=0x01 V=0x03

0x03 便是 rsa 公钥的 e 值。

 
喜欢 0
分享