标签:break 支持 links extract dia follow 结构 instance strong
接触GMSSL一段时间了,总结一点点想法
证书:DER格式、PEM格式
.DER = DER扩展用于二进制DER编码证书。
.PEM = PEM扩展用于不同类型的X.509v3文件,是以“ - BEGIN ...”前缀的ASCII(Base64)数据。
DER格式是二进制的,PEM则是文本格式,
实际上,PEM格式的内容在去掉"---BEGIN"的内容,采取BASE64解码,得到的BLOG内容,就是DER格式的内容
DER的内容,实际上在GMSSL、OPENSSL中,都是以ASN.1格式进行编码的内存BLOB
查看GMSSL的代码,就可以看到公钥、私钥各自的ASN格式化支持代码
RSA的公钥、私钥支持代码如下:
ASN1_SEQUENCE_cb(RSAPrivateKey, rsa_cb) = {
ASN1_SIMPLE(RSA, version, LONG),
ASN1_SIMPLE(RSA, n, BIGNUM),
ASN1_SIMPLE(RSA, e, BIGNUM),
ASN1_SIMPLE(RSA, d, CBIGNUM),
ASN1_SIMPLE(RSA, p, CBIGNUM),
ASN1_SIMPLE(RSA, q, CBIGNUM),
ASN1_SIMPLE(RSA, dmp1, CBIGNUM),
ASN1_SIMPLE(RSA, dmq1, CBIGNUM),
ASN1_SIMPLE(RSA, iqmp, CBIGNUM)
} ASN1_SEQUENCE_END_cb(RSA, RSAPrivateKey)
ASN1_SEQUENCE_cb(RSAPublicKey, rsa_cb) = {
ASN1_SIMPLE(RSA, n, BIGNUM),
ASN1_SIMPLE(RSA, e, BIGNUM),
} ASN1_SEQUENCE_END_cb(RSA, RSAPublicKey)
对于BIGNUM,在格式化时,会先输出一个长度字节(1 byte),再依次输出内容
SM2只定义了密文中的ASN.1的格式化支持代码,如下:
ASN1_SEQUENCE(SM2CiphertextValue) = {
ASN1_SIMPLE(SM2CiphertextValue, xCoordinate, BIGNUM),
ASN1_SIMPLE(SM2CiphertextValue, yCoordinate, BIGNUM),
ASN1_SIMPLE(SM2CiphertextValue, hash, ASN1_OCTET_STRING),
ASN1_SIMPLE(SM2CiphertextValue, ciphertext, ASN1_OCTET_STRING),
} ASN1_SEQUENCE_END(SM2CiphertextValue)
这儿实际定义了密文的三块C1/C2/C3,C1=(x+y)的内容,C2是ciphertext部分,C3是hash部分
至于ASN.1实际的BLOB内存编码,从RSA的公、私钥分析文件可以看出,链接:https://etherhack.co.uk/asymmetric/docs/rsa_key_breakdown.html
参考如下:
OpenSSL 1024 bit RSA Private Key Breakdown
On Linux, using the following command generated this key:
openssl genrsa -out rsa_1024_priv.pem 1024
To understand how the key is broken down into its respective components, execute the following additional command:
openssl rsa -text -in rsa_1024_priv.pem
Alternatively, you can do what I did and breakdown the individual components by hand - in order to learn how the data structure actually works.
Firstly, the data block has to be decoded from it‘s standard Base64 format, so remove the "-----BEGIN..." lines at the start and end of the file and convert the data into Hexadecimal.
The data block is now in a format we can read (sort of).
Using Abstract Syntax Notation 1 (or ASN.1), we can read and identify the Distinguished Encoding Rules (DER) encoded components contained within this data.
Although the only data stored in this instance of the ASN format is of type Integer, other standard variable types are listed here for clarity. When the Integer type is used in this context, it is followed by the length in bytes for the following data object, and then the data itself, as can be seen below.
- 0x02 == Integer
- 0x03 == Bit String
- 0x04 == Octet String
- 0x05 == NULL
- 0x06 == Object Identifier
- 0x10 == "Sequence" and "Sequence of"
- 0x11 == "Set" and "Set of"
- 0x13 == Printable String
- 0x14 == T61 String
- 0x16 == IA5 String
- 0x17 == UTC Time
- 0x30 82 == ASN1 Sequence
1024 bit RSA Private Key in Base64 Format
-----BEGIN RSA PRIVATE KEY-----
MIICXgIBAAKBgQDHikastc8+I81zCg/qWW8dMr8mqvXQ3qbPAmu0RjxoZVI47tvs
kYlFAXOf0sPrhO2nUuooJngnHV0639iTTEYG1vckNaW2R6U5QTdQ5Rq5u+uV3pMk
7w7Vs4n3urQ6jnqt2rTXbC1DNa/PFeAZatbf7ffBBy0IGO0zc128IshYcwIDAQAB
AoGBALTNl2JxTvq4SDW/3VH0fZkQXWH1MM10oeMbB2qO5beWb11FGaOO77nGKfWc
bYgfp5Ogrql4yhBvLAXnxH8bcqqwORtFhlyV68U1y4R+8WxDNh0aevxH8hRS/1X5
031DJm1JlU0E+vStiktN0tC3ebH5hE+1OxbIHSZ+WOWLYX7JAkEA5uigRgKp8ScG
auUijvdOLZIhHWq7y5Wz+nOHUuDw8P7wOTKU34QJAoWEe771p9Pf/GTA/kr0BQnP
QvWUDxGzJwJBAN05C6krwPeryFKrKtjOGJIniIoY72wRnoNcdEEs3HDRhf48YWFo
riRbZylzzzNFy/gmzT6XJQTfktGqq+FZD9UCQGIJaGrxHJgfmpDuAhMzGsUsYtTr
iRox0D1Iqa7dhE693t5aBG010OF6MLqdZA1CXrn5SRtuVVaCSLZEL/2J5UcCQQDA
d3MXucNnN4NPuS/L9HMYJWD7lPoosaORcgyK77bSSNgk+u9WSjbH1uYIAIPSffUZ
bti+jc1dUg5wb+aeZlgJAkEAurrpmpqj5vg087ZngKfFGR5rozDiTsK5DceTV97K
a3Y+Nzl+XWTxDBWk4YPh2ZlKv402hZEfWBYxUDn5ZkH/bw==
-----END RSA PRIVATE KEY-----
Private Key in Hexadecimal Format
In this example, the Hexadecimal values have been paired for clarity, but in the other examples (see links at the top of this page) the values have not been separated.
Parts highlighted below, in order:
- ASN.1 Header
- Algorithm Version
- Modulus
- Public Exponent
- Private Exponent
- prime1
- prime2
- exponent 1
- exponent 2
- coefficient
-----BEGIN RSA PRIVATE KEY-----
30 82 02 5e 02 01 00 02 81 81 00 c7 8a 46 ac b5 cf 3e 23 cd 73 0a
0f ea 59 6f 1d 32 bf 26 aa f5 d0 de a6 cf 02 6b b4 46 3c 68 65 52
38 ee db ec 91 89 45 01 73 9f d2 c3 eb 84 ed a7 52 ea 28 26 78 27
1d 5d 3a df d8 93 4c 46 06 d6 f7 24 35 a5 b6 47 a5 39 41 37 50 e5
1a b9 bb eb 95 de 93 24 ef 0e d5 b3 89 f7 ba b4 3a 8e 7a ad da b4
d7 6c 2d 43 35 af cf 15 e0 19 6a d6 df ed f7 c1 07 2d 08 18 ed 33
73 5d bc 22 c8 58 73 02 03 01 00 01 02 81 81 00 b4 cd 97 62 71 4e
fa b8 48 35 bf dd 51 f4 7d 99 10 5d 61 f5 30 cd 74 a1 e3 1b 07 6a
8e e5 b7 96 6f 5d 45 19 a3 8e ef b9 c6 29 f5 9c 6d 88 1f a7 93 a0
ae a9 78 ca 10 6f 2c 05 e7 c4 7f 1b 72 aa b0 39 1b 45 86 5c 95 eb
c5 35 cb 84 7e f1 6c 43 36 1d 1a 7a fc 47 f2 14 52 ff 55 f9 d3 7d
43 26 6d 49 95 4d 04 fa f4 ad 8a 4b 4d d2 d0 b7 79 b1 f9 84 4f b5
3b 16 c8 1d 26 7e 58 e5 8b 61 7e c9 02 41 00 e6 e8 a0 46 02 a9 f1
27 06 6a e5 22 8e f7 4e 2d 92 21 1d 6a bb cb 95 b3 fa 73 87 52 e0
f0 f0 fe f0 39 32 94 df 84 09 02 85 84 7b be f5 a7 d3 df fc 64 c0
fe 4a f4 05 09 cf 42 f5 94 0f 11 b3 27 02 41 00 dd 39 0b a9 2b c0
f7 ab c8 52 ab 2a d8 ce 18 92 27 88 8a 18 ef 6c 11 9e 83 5c 74 41
2c dc 70 d1 85 fe 3c 61 61 68 ae 24 5b 67 29 73 cf 33 45 cb f8 26
cd 3e 97 25 04 df 92 d1 aa ab e1 59 0f d5 02 40 62 09 68 6a f1 1c
98 1f 9a 90 ee 02 13 33 1a c5 2c 62 d4 eb 89 1a 31 d0 3d 48 a9 ae
dd 84 4e bd de de 5a 04 6d 35 d0 e1 7a 30 ba 9d 64 0d 42 5e b9 f9
49 1b 6e 55 56 82 48 b6 44 2f fd 89 e5 47 02 41 00 c0 77 73 17 b9
c3 67 37 83 4f b9 2f cb f4 73 18 25 60 fb 94 fa 28 b1 a3 91 72 0c
8a ef b6 d2 48 d8 24 fa ef 56 4a 36 c7 d6 e6 08 00 83 d2 7d f5 19
6e d8 be 8d cd 5d 52 0e 70 6f e6 9e 66 58 09 02 41 00 ba ba e9 9a
9a a3 e6 f8 34 f3 b6 67 80 a7 c5 19 1e 6b a3 30 e2 4e c2 b9 0d c7
93 57 de ca 6b 76 3e 37 39 7e 5d 64 f1 0c 15 a4 e1 83 e1 d9 99 4a
bf 8d 36 85 91 1f 58 16 31 50 39 f9 66 41 ff 6f
-----END RSA PRIVATE KEY-----
Extracted Key Components, in order of appearance
Private-Key:
header:
30 82 02 5e (0x3082 == ASN.1 Sequence)
separator:
02 01 (0x02 == Integer and 0x01 == 1 byte long)
algorithm version:
00 (0x00 == version zero)
separator:
02 81 81 (0x02 == Integer and 0x81 == 129 bytes long)
modulus: (129 bytes - starts with a null (0x00), remove this.)
00 c7 8a 46 ac b5 cf 3e 23 cd 73 0a 0f ea 59
6f 1d 32 bf 26 aa f5 d0 de a6 cf 02 6b b4 46
3c 68 65 52 38 ee db ec 91 89 45 01 73 9f d2
c3 eb 84 ed a7 52 ea 28 26 78 27 1d 5d 3a df
d8 93 4c 46 06 d6 f7 24 35 a5 b6 47 a5 39 41
37 50 e5 1a b9 bb eb 95 de 93 24 ef 0e d5 b3
89 f7 ba b4 3a 8e 7a ad da b4 d7 6c 2d 43 35
af cf 15 e0 19 6a d6 df ed f7 c1 07 2d 08 18
ed 33 73 5d bc 22 c8 58 73
separator:
02 03 (0x02 == Integer and 0x03 == 3 bytes long)
public exponent: (3 bytes)
01 00 01 (Integer value 65537, Fermat Number F4)
separator:
02 81 81 (0x02 == Integer and 0x81 == 129 bytes long)
private exponent: (129 bytes - starts with a null, remove this)
00 b4 cd 97 62 71 4e fa b8 48 35 bf dd 51 f4
7d 99 10 5d 61 f5 30 cd 74 a1 e3 1b 07 6a 8e
e5 b7 96 6f 5d 45 19 a3 8e ef b9 c6 29 f5 9c
6d 88 1f a7 93 a0 ae a9 78 ca 10 6f 2c 05 e7
c4 7f 1b 72 aa b0 39 1b 45 86 5c 95 eb c5 35
cb 84 7e f1 6c 43 36 1d 1a 7a fc 47 f2 14 52
ff 55 f9 d3 7d 43 26 6d 49 95 4d 04 fa f4 ad
8a 4b 4d d2 d0 b7 79 b1 f9 84 4f b5 3b 16 c8
1d 26 7e 58 e5 8b 61 7e c9
separator:
02 41 (0x02 == Integer and 0x41 == 65 bytes long)
prime1: (65 bytes - starts with a null, remove this)
00 e6 e8 a0 46 02 a9 f1 27 06 6a e5 22 8e f7
4e 2d 92 21 1d 6a bb cb 95 b3 fa 73 87 52 e0
f0 f0 fe f0 39 32 94 df 84 09 02 85 84 7b be
f5 a7 d3 df fc 64 c0 fe 4a f4 05 09 cf 42 f5
94 0f 11 b3 27
separator:
02 41 (0x02 == Integer and 0x41 == 65 bytes long)
prime2: (65 bytes - starts with a null, remove this)
00 dd 39 0b a9 2b c0 f7 ab c8 52 ab 2a d8 ce
18 92 27 88 8a 18 ef 6c 11 9e 83 5c 74 41 2c
dc 70 d1 85 fe 3c 61 61 68 ae 24 5b 67 29 73
cf 33 45 cb f8 26 cd 3e 97 25 04 df 92 d1 aa
ab e1 59 0f d5
separator:
02 40 (0x02 == Integer and 0x40 == 64 bytes long)
exponent1: (64 bytes)
62 09 68 6a f1 1c 98 1f 9a 90 ee 02 13 33 1a
c5 2c 62 d4 eb 89 1a 31 d0 3d 48 a9 ae dd 84
4e bd de de 5a 04 6d 35 d0 e1 7a 30 ba 9d 64
0d 42 5e b9 f9 49 1b 6e 55 56 82 48 b6 44 2f
fd 89 e5 47
separator:
02 41 (0x02 == Integer and 0x41 == 65 bytes long)
exponent2: (65 bytes - starts with a null, remove this)
00 c0 77 73 17 b9 c3 67 37 83 4f b9 2f cb f4
73 18 25 60 fb 94 fa 28 b1 a3 91 72 0c 8a ef
b6 d2 48 d8 24 fa ef 56 4a 36 c7 d6 e6 08 00
83 d2 7d f5 19 6e d8 be 8d cd 5d 52 0e 70 6f
e6 9e 66 58 09
separator:
02 41 (0x02 == Integer and 0x41 == 65 bytes long)
coefficient: (65 bytes - always starts with a null)
00 ba ba e9 9a 9a a3 e6 f8 34 f3 b6 67 80 a7
c5 19 1e 6b a3 30 e2 4e c2 b9 0d c7 93 57 de
ca 6b 76 3e 37 39 7e 5d 64 f1 0c 15 a4 e1 83
e1 d9 99 4a bf 8d 36 85 91 1f 58 16 31 50 39
f9 66 41 ff 6f
SSL 1024 bit RSA Public Key Breakdown
Using Linux, the following command generated this public key:
openssl rsa -pubout -in rsa_1024_priv.pem -out rsa_1024_pub.pem
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDHikastc8+I81zCg/qWW8dMr8m
qvXQ3qbPAmu0RjxoZVI47tvskYlFAXOf0sPrhO2nUuooJngnHV0639iTTEYG1vck
NaW2R6U5QTdQ5Rq5u+uV3pMk7w7Vs4n3urQ6jnqt2rTXbC1DNa/PFeAZatbf7ffB
By0IGO0zc128IshYcwIDAQAB
-----END PUBLIC KEY-----
Public Key in Hexadecimal Format
Parts in bold, in order:
-----BEGIN PUBLIC KEY-----
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 c7 8a 46 ac b5 cf 3e 23 cd 73 0a 0f ea 59 6f
1d 32 bf 26 aa f5 d0 de a6 cf 02 6b b4 46 3c 68 65 52 38 ee db ec
91 89 45 01 73 9f d2 c3 eb 84 ed a7 52 ea 28 26 78 27 1d 5d 3a df
d8 93 4c 46 06 d6 f7 24 35 a5 b6 47 a5 39 41 37 50 e5 1a b9 bb eb
95 de 93 24 ef 0e d5 b3 89 f7 ba b4 3a 8e 7a ad da b4 d7 6c 2d 43
35 af cf 15 e0 19 6a d6 df ed f7 c1 07 2d 08 18 ed 33 73 5d bc 22
c8 58 73 02 03 01 00 01
-----END PUBLIC KEY-----
Extracted Public Key Components
header:
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
separator:
02 81 81
modulus:
00 c7 8a 46 ac b5 cf 3e 23 cd 73 0a 0f ea 59
6f 1d 32 bf 26 aa f5 d0 de a6 cf 02 6b b4 46
3c 68 65 52 38 ee db ec 91 89 45 01 73 9f d2
c3 eb 84 ed a7 52 ea 28 26 78 27 1d 5d 3a df
d8 93 4c 46 06 d6 f7 24 35 a5 b6 47 a5 39 41
37 50 e5 1a b9 bb eb 95 de 93 24 ef 0e d5 b3
89 f7 ba b4 3a 8e 7a ad da b4 d7 6c 2d 43 35
af cf 15 e0 19 6a d6 df ed f7 c1 07 2d 08 18
ed 33 73 5d bc 22 c8 58 73
separator:
02 03
public exponent:
01 00 01
[W3C Valid CSS 2]
[W3C Valid XHTML 1.1]
另外,参考学习此链接:https://tls.mbed.org/kb/cryptography/asn1-key-structures-in-der-and-pem
快速翻译版本如下:
介绍
每个人都喜欢PEM和用于以便携式格式保存加密密钥和证书的ASN.1结构。好吧..如果他们真的被记录下来,每个人都会这样做。但是,找到每个DER或PEM格式文件中的结构是一个很大的壮举。
由于我们需要这些信息,我们也会在这里分享,以帮助他人寻求知识和理解;)
ASN.1和DER编码
在RSA,PKCS#1和SSL / TLS社区内,ASN.1的可分辨编码规则(DER)编码用于以便携式格式表示密钥,证书等。尽管ASN.1不是最容易理解的表示格式并且带来了很多复杂性,但它确实有其优点。证书或密钥信息存储在ASN.1的二进制DER中,提供RSA,SSL和TLS的应用程序应处理DER编码以读取信息。
PEM文件
由于DER编码导致编码数据的真正二进制表示,因此设计了一种格式,以便能够以可打印字符的编码方式发送这些格式,以便您可以实际邮寄这些内容。我现在关注的格式是PEM格式。
我们将看到的大多数PEM格式的文??件是由OpenSSL在生成或导出RSA私钥或公钥和X509证书时生成的。
本质上,PEM文件只是DER编码数据的base64编码版本。为了区分外部DER编码字符串中的数据类型,数据周围存在页眉和页脚。PEM编码文件的示例是:
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMYfnvWtC8Id5bPKae5yXSxQTt
+Zpul6AnnZWfI2TtIarvjHBFUtXRo96y7hoL4VWOPKGCsRqMFDkrbeUjRrx8iL91
4/srnyf6sh9c8Zk04xEOpK1ypvBz+Ks4uZObtjnnitf0NBGdjMKxveTq+VE7BWUI
yQjtQ8mbDOsiLLvh7wIDAQAB
-----END PUBLIC KEY-----
第一行和最后一行表示内部应该预期的DER格式。里面的数据是DER编码信息的base64编码版本。
格式
所以这一切都很好。但是在每个不同的文件中你应该期待什么结构?请看下面的不同格式的解释。
RSA公钥文件(PKCS#1)
RSA公钥PEM文件特定于RSA密钥。
它以标签开头和结尾:
-----BEGIN RSA PUBLIC KEY-----
BASE64 ENCODED DATA
-----END RSA PUBLIC KEY-----
在base64编码数据中,存在以下DER结构:
RSAPublicKey ::= SEQUENCE {
modulus INTEGER, -- n
publicExponent INTEGER -- e
}
公钥文件(PKCS#8)
由于RSA不是专门用于X509和SSL / TLS,因此PKCS#8形式提供了更通用的密钥格式,它标识了公钥的类型并包含相关数据。
它以标签开头和结尾:
-----BEGIN PUBLIC KEY-----
BASE64 ENCODED DATA
-----END PUBLIC KEY-----
在base64编码数据中,存在以下DER结构:
PublicKeyInfo ::= SEQUENCE {
algorithm AlgorithmIdentifier,
PublicKey BIT STRING
}
AlgorithmIdentifier ::= SEQUENCE {
algorithm OBJECT IDENTIFIER,
parameters ANY DEFINED BY algorithm OPTIONAL
}
因此,对于RSA公钥,OID是1.2.840.113549.1.1.1,并且有一个RSAPublicKey作为PublicKey密钥数据bitstring。
RSA私钥文件(PKCS#1)
RSA私钥PEM文件特定于RSA密钥。
它以标签开头和结尾:
-----BEGIN RSA PRIVATE KEY-----
BASE64 ENCODED DATA
-----END RSA PRIVATE KEY-----
在base64编码数据中,存在以下DER结构:
RSAPrivateKey ::= SEQUENCE {
version Version,
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
}
私钥文件(PKCS#8)
由于RSA不是专门用于X509和SSL / TLS,因此PKCS#8形式的更通用密钥格式可用于标识私钥的类型并包含相关数据。
未加密的PKCS#8编码数据以标签开头和结尾:
-----BEGIN PRIVATE KEY-----
BASE64 ENCODED DATA
-----END PRIVATE KEY-----
在base64编码数据中,存在以下DER结构:
PrivateKeyInfo ::= SEQUENCE {
version Version,
algorithm AlgorithmIdentifier,
PrivateKey OCTET STRING
}
AlgorithmIdentifier ::= SEQUENCE {
algorithm OBJECT IDENTIFIER,
parameters ANY DEFINED BY algorithm OPTIONAL
}
因此对于RSA私钥,OID是1.2.840.113549.1.1.1并且存在RSAPrivateKey作为PrivateKey密钥数据八位字节串。
加密的PKCS#8编码数据以标签开头和结尾:
-----BEGIN ENCRYPTED PRIVATE KEY-----
BASE64 ENCODED DATA
-----END ENCRYPTED PRIVATE KEY-----
在base64编码数据中,存在以下DER结构:
EncryptedPrivateKeyInfo ::= SEQUENCE {
encryptionAlgorithm EncryptionAlgorithmIdentifier,
encryptedData EncryptedData
}
EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
EncryptedData ::= OCTET STRING
EncryptedData OCTET STRING是PKCS#8 PrivateKeyInfo(见上文)。
这有帮助吗?
GMSSL学习总结1
标签:break 支持 links extract dia follow 结构 instance strong
原文地址:https://www.cnblogs.com/eaglexmw/p/11140505.html