一般咱们遇到过的X509证书都是基于RSA-SHA1算法的,目前国家在大力推行国密算法,将来银行发行的IC卡也都是基于PBOC3.0支持国密算法的,所以咱们来学习一下如何验证SM2国密证书的合法性。至于SM2与SM3的算法实现不在本文讨论范围以内,能够用openssl、BouncyCastle.Crypto.dll等第三方库来实现。算法
SM2国密证书与RSA证书同样,通常内容都是以BASE64格式编码的,以网上下载的一个自签名证书为例:学习
MIIB5jCCAZECAQAwVDELMAkGA1UEBhMCQ04xCzAJBgNVBAgTAmZnMQ0wCwYDVQQHEwRzZG编码
ZnMQwwCgYDVQQKEwM0NXkxDTALBgNVBAsTBGFlcnQxDDAKBgNVBAMTA2RmZzCCATQwge0Gspa
CCqBHIFFAYItMIHgAgEBMCwGByqGSM49AQECIQCFQtaeTARPGOi5JDW/b/feRXKDkVxFUX1yLtuLssl
CPHfwzBEBCB4eWi0+jLD/SQXhC5zu/7/LzyEi2gx1+DsZSKLOTfkmAQgY+TG07I7DISc+EJBSEv+ci
SPYdWaWxa6BubhLR2ifFJJoEQQRCHevWG2LqtnRkNOvDzDFeMiILO63VC9xMTmwUf+3UPQaAUSopenssl
vLtCwH1HNJ0hU7cMTl1/38v6NuoahYQbnkbgmiAiEAhULWnkwETxjouSQ1v2/33Sl3IGMEhWKNWuqt
dO58MuebcCAQEDQgAEwze7gBfVcry8A7QigOQxFPvv3/HZpOCIZq+46+z+BUeuXTxYDl00i+eh23it
0HmYP5pKWYZiZ9lR3bvcxFd17YKjAMBggqgRyBRQGDdQUAA0EAhneSdWonUMXL0Sk4vpzPtqZtable
vUddbYo/Bb7o3a+Tek4+v/kp8q7hvA+2BubXpTSAE2AjE0qytc4THB++vmI75Lg==
通过BASE64解码后是TLV格式,再解析获得以下表格:
TAG |
名称 |
长度 |
值 |
|||||||
30 |
未知标签 |
1E6 |
||||||||
30 |
未知标签 |
191 |
||||||||
02 |
未知标签 |
01 |
00 |
|||||||
30 |
未知标签 |
54 |
||||||||
31 |
未知标签 |
0B |
||||||||
30 |
未知标签 |
09 |
||||||||
06 |
未知标签 |
03 |
55 04 06 |
|||||||
13 |
未知标签 |
02 |
43 4E |
|||||||
31 |
未知标签 |
0B |
||||||||
30 |
未知标签 |
09 |
||||||||
06 |
未知标签 |
03 |
55 04 08 |
|||||||
13 |
未知标签 |
02 |
66 67 |
|||||||
31 |
未知标签 |
0D |
||||||||
30 |
未知标签 |
0B |
||||||||
06 |
未知标签 |
03 |
55 04 07 |
|||||||
13 |
未知标签 |
04 |
73 64 66 67 |
|||||||
31 |
未知标签 |
0C |
||||||||
30 |
未知标签 |
0A |
||||||||
06 |
未知标签 |
03 |
55 04 0A |
|||||||
13 |
未知标签 |
03 |
34 35 79 |
|||||||
31 |
未知标签 |
0D |
||||||||
30 |
未知标签 |
0B |
||||||||
06 |
未知标签 |
03 |
55 04 0B |
|||||||
13 |
未知标签 |
04 |
61 65 72 74 |
|||||||
31 |
未知标签 |
0C |
||||||||
30 |
未知标签 |
0A |
||||||||
06 |
未知标签 |
03 |
55 04 03 |
|||||||
13 |
未知标签 |
03 |
64 66 67 |
|||||||
30 |
未知标签 |
134 |
||||||||
30 |
未知标签 |
ED |
||||||||
06 |
未知标签 |
08 |
2A 81 1C 81 45 01 82 2D |
|||||||
30 |
未知标签 |
E0 |
||||||||
02 |
未知标签 |
01 |
01 |
|||||||
30 |
未知标签 |
2C |
||||||||
06 |
未知标签 |
07 |
2A 86 48 CE 3D 01 01 |
|||||||
02 |
未知标签 |
21 |
00 85 42 D6 9E 4C 04 4F 18 E8 B9 24 35 BF 6F F7 DE 45 72 83 91 5C 45 51 7D 72 2E DB 8B 08 F1 DF C3 |
|||||||
30 |
未知标签 |
44 |
||||||||
04 |
未知标签 |
20 |
78 79 68 B4 FA 32 C3 FD 24 17 84 2E 73 BB FE FF 2F 3C 84 8B 68 31 D7 E0 EC 65 22 8B 39 37 E4 98 |
|||||||
04 |
未知标签 |
20 |
63 E4 C6 D3 B2 3B 0C 84 9C F8 42 41 48 4B FE 48 F6 1D 59 A5 B1 6B A0 6E 6E 12 D1 DA 27 C5 24 9A |
|||||||
04 |
未知标签 |
41 |
04 42 1D EB D6 1B 62 EA B6 74 64 34 EB C3 CC 31 5E 32 22 0B 3B AD D5 0B DC 4C 4E 6C 14 7F ED D4 3D 06 80 51 2B CB B4 2C 07 D4 73 49 D2 15 3B 70 C4 E5 D7 FD FC BF A3 6E A1 A8 58 41 B9 E4 6E 09 A2 |
|||||||
02 |
未知标签 |
21 |
00 85 42 D6 9E 4C 04 4F 18 E8 B9 24 35 BF 6F F7 DD 29 77 20 63 04 85 62 8D 5A E7 4E E7 C3 2E 79 B7 |
|||||||
02 |
未知标签 |
01 |
01 |
|||||||
03 |
未知标签 |
42 |
00 04 C3 37 BB 80 17 D5 72 BC BC 03 B4 22 80 E4 31 14 FB EF DF F1 D9 A4 E0 88 66 AF B8 EB EC FE 05 47 AE 5D 3C 58 0E 5D 34 8B E7 A1 DB 7D 07 99 83 F9 A4 A5 98 66 26 7D 95 1D DB BD CC 45 77 5E D8 2A 04表示SM2密钥 后面32字节表示公钥X 后面32字节表示公钥Y |
|||||||
30 |
未知标签 |
0C |
||||||||
06 |
未知标签 |
08 |
2A 81 1C 81 45 01 83 75 |
|||||||
05 |
未知标签 |
00 |
||||||||
03 |
未知标签 |
41 |
00 86 77 92 75 6A 27 50 C5 CB D1 29 38 BE 9C CF B6 A6 6F 51 D7 5B 62 8F C1 6F BA 37 6B E4 DE 93 8F AF FE 4A 7C AB B8 6F 03 ED 81 B9 B5 E9 4D 20 04 D8 08 C4 D2 AC AD 73 84 C7 07 EF AF 98 8E F9 2E 签名后的数据 |
从上面的表格中能够获得SM2公钥与签名后数据:
公钥X:C3 37 BB 80 17 D5 72 BC BC 03 B4 22 80 E4 31 14 FB EF DF F1 D9 A4 E0 88 66 AF B8 EB EC FE 05 47
公钥Y:AE 5D 3C 58 0E 5D 34 8B E7 A1 DB 7D 07 99 83 F9 A4 A5 98 66 26 7D 95 1D DB BD CC 45 77 5E D8 2A
签名后的数据:86 77 92 75 6A 27 50 C5 CB D1 29 38 BE 9C CF B6 A6 6F 51 D7 5B 62 8F C1 6F BA 37 6B E4 DE 93 8F AF FE 4A 7C AB B8 6F 03 ED 81 B9 B5 E9 4D 20 04 D8 08 C4 D2 AC AD 73 84 C7 07 EF AF 98 8E F9 2E
接下来取证书数据的第二层TAG的第一个TAG 30(即表格中斜体部分数据),对数据进行SM3计算后获得
HASH值:C8 72 D5 09 1D 2A 11 67 28 65 F5 C4 55 8E C2 3F A9 2F 53 BC E5 90 96 8D AC 91 20 9B 63 BD AD 34
用SM2公钥验签便可成功。
接下来用国密局的自签名SM2证书来示范,数据处理有所不一样
MIICaDCCAgygAwIBAgIJAK8ocl2Y0zFDMAwGCCqBHM9VAYN1BQAwfTELMAkGA1UEBgwCY24xCz
AJBgNVBAgMAmJqMQswCQYDVQQHDAJiajEPMA0GA1UECgwGdG9wc2VjMQ8wDQYDVQQLDAZ0b
3BzZWMxETAPBgNVBAMMCFRvcHNlY0NBMR8wHQYJKoZIhvcNAQkBDBBiakB0b3BzZWMuY29tLm
NuMB4XDTEyMDYyNDA3NTQzOVoXDTMyMDYyMDA3NTQzOVowfTELMAkGA1UEBgwCY24xCzAJB
gNVBAgMAmJqMQswCQYDVQQHDAJiajEPMA0GA1UECgwGdG9wc2VjMQ8wDQYDVQQLDAZ0b3Bz
ZWMxETAPBgNVBAMMCFRvcHNlY0NBMR8wHQYJKoZIhvcNAQkBDBBiakB0b3BzZWMuY29tLmNuM
FkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE1pwvHuw7+2uVswwoCFx3sSXXepw5Ul2BkHaPN9ayB
bWJ3NMWu+fYmp3CGRfxd5nmmFMfXm4+EL0xNwslnD+Bw6NzMHEwDwYDVR0TAQH/BAUwAwEB
/zAdBgNVHQ4EFgQUjl2QNHhYuqrYcNi9+6aoXntWO2QwHwYDVR0jBBgwFoAUjl2QNHhYuqrYcNi9+
6aoXntWO2QwCwYDVR0PBAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIAVzAMBggqgRzPVQGDdQU
AA0gAMEUCIQCGqTACsUVb7KXmi8E5pqJtyWpKj1Mm0vPokvH6ondQKwIgFH5vrHQjncD1e9avYQB
SF9fxplgZ/tdU9nxDgh2HnRU=
通过BASE64解码后再解析TLV格式,获得以下表格
TAG |
名称 |
长度 |
值 |
||||||||
30 |
未知标签 |
268 |
|||||||||
30 |
未知标签 |
20C |
|||||||||
A0 |
未知标签 |
03 |
|||||||||
02 |
未知标签 |
01 |
02 |
||||||||
02 |
未知标签 |
09 |
00 AF 28 72 5D 98 D3 31 43 |
||||||||
30 |
未知标签 |
0C |
|||||||||
06 |
未知标签 |
08 |
2A 81 1C CF 55 01 83 75 |
||||||||
05 |
未知标签 |
00 |
|||||||||
30 |
未知标签 |
7D |
|||||||||
31 |
未知标签 |
0B |
|||||||||
30 |
未知标签 |
09 |
|||||||||
06 |
未知标签 |
03 |
55 04 06 |
||||||||
0C |
未知标签 |
02 |
63 6E |
||||||||
31 |
未知标签 |
0B |
|||||||||
30 |
未知标签 |
09 |
|||||||||
06 |
未知标签 |
03 |
55 04 08 |
||||||||
0C |
未知标签 |
02 |
62 6A |
||||||||
31 |
未知标签 |
0B |
|||||||||
30 |
未知标签 |
09 |
|||||||||
06 |
未知标签 |
03 |
55 04 07 |
||||||||
0C |
未知标签 |
02 |
62 6A |
||||||||
31 |
未知标签 |
0F |
|||||||||
30 |
未知标签 |
0D |
|||||||||
06 |
未知标签 |
03 |
55 04 0A |
||||||||
0C |
未知标签 |
06 |
74 6F 70 73 65 63 |
||||||||
31 |
未知标签 |
0F |
|||||||||
30 |
未知标签 |
0D |
|||||||||
06 |
未知标签 |
03 |
55 04 0B |
||||||||
0C |
未知标签 |
06 |
74 6F 70 73 65 63 |
||||||||
31 |
未知标签 |
11 |
|||||||||
30 |
未知标签 |
0F |
|||||||||
06 |
未知标签 |
03 |
55 04 03 |
||||||||
0C |
未知标签 |
08 |
54 6F 70 73 65 63 43 41 |
||||||||
31 |
未知标签 |
1F |
|||||||||
30 |
未知标签 |
1D |
|||||||||
06 |
未知标签 |
09 |
2A 86 48 86 F7 0D 01 09 01 |
||||||||
0C |
未知标签 |
10 |
62 6A 40 74 6F 70 73 65 63 2E 63 6F 6D 2E 63 6E |
||||||||
30 |
未知标签 |
1E |
|||||||||
17 |
未知标签 |
0D |
31 32 30 36 32 34 30 37 35 34 33 39 5A |
||||||||
17 |
未知标签 |
0D |
33 32 30 36 32 30 30 37 35 34 33 39 5A |
||||||||
30 |
未知标签 |
7D |
|||||||||
31 |
未知标签 |
0B |
|||||||||
30 |
未知标签 |
09 |
|||||||||
06 |
未知标签 |
03 |
55 04 06 |
||||||||
0C |
未知标签 |
02 |
63 6E |
||||||||
31 |
未知标签 |
0B |
|||||||||
30 |
未知标签 |
09 |
|||||||||
06 |
未知标签 |
03 |
55 04 08 |
||||||||
0C |
未知标签 |
02 |
62 6A |
||||||||
31 |
未知标签 |
0B |
|||||||||
30 |
未知标签 |
09 |
|||||||||
06 |
未知标签 |
03 |
55 04 07 |
||||||||
0C |
未知标签 |
02 |
62 6A |
||||||||
31 |
未知标签 |
0F |
|||||||||
30 |
未知标签 |
0D |
|||||||||
06 |
未知标签 |
03 |
55 04 0A |
||||||||
0C |
未知标签 |
06 |
74 6F 70 73 65 63 |
||||||||
31 |
未知标签 |
0F |
|||||||||
30 |
未知标签 |
0D |
|||||||||
06 |
未知标签 |
03 |
55 04 0B |
||||||||
0C |
未知标签 |
06 |
74 6F 70 73 65 63 |
||||||||
31 |
未知标签 |
11 |
|||||||||
30 |
未知标签 |
0F |
|||||||||
06 |
未知标签 |
03 |
55 04 03 |
||||||||
0C |
未知标签 |
08 |
54 6F 70 73 65 63 43 41 |
||||||||
31 |
未知标签 |
1F |
|||||||||
30 |
未知标签 |
1D |
|||||||||
06 |
未知标签 |
09 |
2A 86 48 86 F7 0D 01 09 01 |
||||||||
0C |
未知标签 |
10 |
62 6A 40 74 6F 70 73 65 63 2E 63 6F 6D 2E 63 6E |
||||||||
30 |
未知标签 |
59 |
|||||||||
30 |
未知标签 |
13 |
|||||||||
06 |
未知标签 |
07 |
2A 86 48 CE 3D 02 01 |
||||||||
06 |
未知标签 |
08 |
2A 81 1C CF 55 01 82 2D |
||||||||
03 |
未知标签 |
42 |
00 04 D6 9C 2F 1E EC 3B FB 6B 95 B3 0C 28 08 5C 77 B1 25 D7 7A 9C 39 52 5D 81 90 76 8F 37 D6 B2 05 B5 89 DC D3 16 BB E7 D8 9A 9D C2 19 17 F1 77 99 E6 98 53 1F 5E 6E 3E 10 BD 31 37 0B 25 9C 3F 81 C3 04表示SM2密钥 后面32字节表示公钥X 后面32字节表示公钥Y |
||||||||
A3 |
未知标签 |
73 |
|||||||||
30 |
未知标签 |
71 |
|||||||||
30 |
未知标签 |
0F |
|||||||||
06 |
未知标签 |
03 |
55 1D 13 |
||||||||
01 |
未知标签 |
01 |
FF |
||||||||
04 |
未知标签 |
05 |
|||||||||
30 |
未知标签 |
03 |
|||||||||
01 |
未知标签 |
01 |
FF |
||||||||
30 |
未知标签 |
1D |
|||||||||
06 |
未知标签 |
03 |
55 1D 0E |
||||||||
04 |
未知标签 |
16 |
|||||||||
04 |
未知标签 |
14 |
8E 5D 90 34 78 58 BA AA D8 70 D8 BD FB A6 A8 5E 7B 56 3B 64 |
||||||||
30 |
未知标签 |
1F |
|||||||||
06 |
未知标签 |
03 |
55 1D 23 |
||||||||
04 |
未知标签 |
18 |
|||||||||
30 |
未知标签 |
16 |
|||||||||
80 |
响应报文模板格式 |
14 |
8E 5D 90 34 78 58 BA AA D8 70 D8 BD FB A6 A8 5E 7B 56 3B 64 |
||||||||
30 |
未知标签 |
0B |
|||||||||
06 |
未知标签 |
03 |
55 1D 0F |
||||||||
04 |
未知标签 |
04 |
|||||||||
03 |
未知标签 |
02 |
01 06 |
||||||||
30 |
未知标签 |
11 |
|||||||||
06 |
未知标签 |
09 |
60 86 48 01 86 F8 42 01 01 |
||||||||
04 |
未知标签 |
04 |
|||||||||
03 |
未知标签 |
02 |
00 57 |
||||||||
30 |
未知标签 |
0C |
|||||||||
06 |
未知标签 |
08 |
2A 81 1C CF 55 01 83 75 |
||||||||
05 |
未知标签 |
00 |
|||||||||
03 |
未知标签 |
48 |
|||||||||
30 |
未知标签 |
45 |
|||||||||
02 |
未知标签 |
21 |
00 86 A9 30 02 B1 45 5B EC A5 E6 8B C1 39 A6 A2 6D C9 6A 4A 8F 53 26 D2 F3 E8 92 F1 FA A2 77 50 2B 签名后的数据R |
||||||||
02 |
未知标签 |
20 |
14 7E 6F AC 74 23 9D C0 F5 7B D6 AF 61 00 52 17 D7 F1 A6 58 19 FE D7 54 F6 7C 43 82 1D 87 9D 15 签名后的数据S |
公钥X:D6 9C 2F 1E EC 3B FB 6B 95 B3 0C 28 08 5C 77 B1 25 D7 7A 9C 39 52 5D 81 90 76 8F 37 D6 B2 05 B5
公钥Y:89 DC D3 16 BB E7 D8 9A 9D C2 19 17 F1 77 99 E6 98 53 1F 5E 6E 3E 10 BD 31 37 0B 25 9C 3F 81 C3
签名后的数据:86 A9 30 02 B1 45 5B EC A5 E6 8B C1 39 A6 A2 6D C9 6A 4A 8F 53 26 D2 F3 E8 92 F1 FA A2 77 50 2B 14 7E 6F AC 74 23 9D C0 F5 7B D6 AF 61 00 52 17 D7 F1 A6 58 19 FE D7 54 F6 7C 43 82 1D 87 9D 15
取证书数据的第二层TAG的第一个TAG 30(即表格中斜体部分数据),获得数据M
注意:国密局的SM2证书验签时,须要对上面的数据进行数据填充(填充方式详见PBOC3.0规范第17部分)。
我猜想是这样的规则:若是签名后的数据不是TLV格式的,则直接进行SM3计算,不然就须要进行数据填充。
下面一步步对数据进行操做:
第一步,组建数据ZA并计算HASH值
00 80(用户ID的bit位长度)
31 32 33 34 35 36 37 38 31 32 33 34 35 36 37 38(用户ID)
FF FF FF FE FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 00 00 00 00 FF FF FF FF FF FF FF FC (椭圆曲线公钥密码算法推荐曲线参数a)
28 E9 FA 9E 9D 9F 5E 34 4D 5A 9E 4B CF 65 09 A7 F3 97 89 F5 15 AB 8F 92 DD BC BD 41 4D 94 0E 93 (椭圆曲线公钥密码算法推荐曲线参数b)
32 C4 AE 2C 1F 19 81 19 5F 99 04 46 6A 39 C9 94 8F E3 0B BF F2 66 0B E1 71 5A 45
89 33 4C 74 C7 (椭圆曲线公钥密码算法推荐曲线参数Gx)
BC 37 36 A2 F4 F6 77 9C 59 BD CE E3 6B 69 21 53 D0 A9 87 7C C6 2A 47 40 02 DF 32 E5 21 39 F0 A0(椭圆曲线公钥密码算法推荐曲线参数Gy)
D6 9C 2F 1E EC 3B FB 6B 95 B3 0C 28 08 5C 77 B1 25 D7 7A 9C 39 52 5D 81 90 76 8F 37 D6 B2 05 B5(公钥X)
89 DC D3 16 BB E7 D8 9A 9D C2 19 17 F1 77 99 E6 98 53 1F 5E 6E 3E 10 BD 31 37 0B 25 9C 3F 81 C3(公钥Y)
对上面数据进行SM3计算获得
4D 38 D2 95 8C A7 FD 2C FA E3 AF 04 48 69 59 CF 92 C8 EF 48 E8 B8 3A 05 C1 12 E7 39 D5 F1 81 D0
第二步,上面的SM3结果加上数据M,再进行SM3计算获得
HASH值:C3 B0 2E 50 0A 8B 60 B7 7D ED CF 6F 4C 11 BE F8 D5 6E 5C DE 70 8C 72 06 56 54 FD 7B 21 67 91 5A
用SM2公钥验签便可成功。