• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 使用SM2密钥对签名验签 (C/C++)
2
3<!--Kit: Crypto Architecture Kit-->
4<!--Subsystem: Security-->
5<!--Owner: @zxz--3-->
6<!--Designer: @lanming-->
7<!--Tester: @PAFT-->
8<!--Adviser: @zengyawen-->
9
10对应的算法规格请查看[签名验签算法规格:SM2](crypto-sign-sig-verify-overview.md#sm2)。
11
12## 在CMake脚本中链接相关动态库
13```txt
14target_link_libraries(entry PUBLIC libohcrypto.so)
15```
16
17## 签名开发步骤
181. 调用[OH_CryptoSign_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptosign_create),指定字符串参数'SM2_256|SM3',创建非对称密钥类型为SM2_256、摘要算法为SM3的Sign实例,用于完成签名操作。
19
202. 调用[OH_CryptoSign_Init](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptosign_init),使用私钥[OH_CryptoPrivKey](../../reference/apis-crypto-architecture-kit/capi-cryptoasymkeyapi-oh-cryptoprivkey.md)初始化Sign实例。
21
223. 调用[OH_CryptoSign_Update](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptosign_update),传入待签名的数据。当前单次update长度没有限制,开发者可以根据数据量判断如何调用update。如果数据量较小,可以直接调用OH_CryptoSign_Final接口一次性传入。
23
244. 调用[OH_CryptoSign_Final](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptosign_final),获取签名后的数据。
25
265. 调用[OH_CryptoSign_Destroy](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptosign_destroy)等释放内存。
27
28```c++
29#include "CryptoArchitectureKit/crypto_common.h"
30#include "CryptoArchitectureKit/crypto_asym_key.h"
31#include "CryptoArchitectureKit/crypto_signature.h"
32
33static OH_Crypto_ErrCode doSm2Test() {
34   OH_CryptoAsymKeyGenerator *keyCtx = nullptr;
35   OH_CryptoKeyPair *keyPair = nullptr;
36   OH_CryptoSign *sign = nullptr;
37
38   uint8_t plainText[] = {
39      0x96, 0x46, 0x2e, 0xde, 0x3f, 0x47, 0xbf, 0xd6, 0x87, 0x48, 0x36, 0x1d, 0x75, 0x35, 0xbd, 0xbc,
40      0x6b, 0x06, 0xe8, 0xb3, 0x68, 0x91, 0x53, 0xce, 0x76, 0x5d, 0x24, 0xda, 0xdc, 0xc4, 0x9f, 0x94,
41   };
42   Crypto_DataBlob msgBlob = {
43      .data = reinterpret_cast<uint8_t *>(plainText),
44      .len = sizeof(plainText)};
45
46   OH_Crypto_ErrCode ret = OH_CryptoAsymKeyGenerator_Create((const char *)"SM2_256", &keyCtx);
47   if (ret != CRYPTO_SUCCESS) {
48      return ret;
49   }
50   ret = OH_CryptoAsymKeyGenerator_Generate(keyCtx, &keyPair);
51   if (ret != CRYPTO_SUCCESS) {
52      OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
53      return ret;
54   }
55
56   OH_CryptoPrivKey *privKey = OH_CryptoKeyPair_GetPrivKey(keyPair);
57   ret = OH_CryptoSign_Create((const char *)"SM2_256|SM3", &sign);
58   if (ret != CRYPTO_SUCCESS) {
59      OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
60      OH_CryptoKeyPair_Destroy(keyPair);
61      return ret;
62   }
63   ret = OH_CryptoSign_Init(sign, privKey);
64   if (ret != CRYPTO_SUCCESS) {
65      OH_CryptoSign_Destroy(sign);
66      OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
67      OH_CryptoKeyPair_Destroy(keyPair);
68      return ret;
69   }
70
71   ret = OH_CryptoSign_Update(sign, &msgBlob);
72   if (ret != CRYPTO_SUCCESS) {
73      OH_CryptoSign_Destroy(sign);
74      OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
75      OH_CryptoKeyPair_Destroy(keyPair);
76      return ret;
77   }
78
79   Crypto_DataBlob signBlob = {.data = nullptr, .len = 0};
80   ret = OH_CryptoSign_Final(sign, nullptr, &signBlob);
81   if (ret != CRYPTO_SUCCESS) {
82      OH_CryptoSign_Destroy(sign);
83      OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
84      OH_CryptoKeyPair_Destroy(keyPair);
85      return ret;
86   }
87   OH_CryptoSign_Destroy(sign);
88   OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
89   OH_CryptoKeyPair_Destroy(keyPair);
90   OH_Crypto_FreeDataBlob(&signBlob);
91   return CRYPTO_SUCCESS;
92}
93```
94
95## 验签开发步骤
96
971. 调用[OH_CryptoVerify_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_create),指定字符串参数'SM2_256|SM3',创建非对称密钥类型为SM2_256、摘要算法为SM3的Verify实例,用于完成验签操作。
98
992. 调用[OH_CryptoVerify_Init](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_init),使用公钥(OH_CryptoPubKey)初始化Verify实例。
100
1013. 调用[OH_CryptoVerify_Update](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_update),传入待验证的数据。当前单次update长度没有限制,开发者可以根据数据量判断如何调用update,如果数据量较小,可以直接调用OH_CryptoVerify_Final接口一次性传入。
102
1034. 调用[OH_CryptoVerify_Final](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_final),对数据进行验签。
104
105```c++
106#include "CryptoArchitectureKit/crypto_common.h"
107#include "CryptoArchitectureKit/crypto_signature.h"
108#include "CryptoArchitectureKit/crypto_asym_key.h"
109
110static bool doTestSm2Signature()
111{
112   OH_CryptoAsymKeyGenerator *keyCtx = nullptr;
113   OH_CryptoKeyPair *keyPair = nullptr;
114   OH_CryptoVerify *verify = nullptr;
115
116   uint8_t plainText[] = {
117      0x96, 0x46, 0x2e, 0xde, 0x3f, 0x47, 0xbf, 0xd6, 0x87, 0x48, 0x36, 0x1d, 0x75, 0x35, 0xbd, 0xbc,
118      0x6b, 0x06, 0xe8, 0xb3, 0x68, 0x91, 0x53, 0xce, 0x76, 0x5d, 0x24, 0xda, 0xdc, 0xc4, 0x9f, 0x94,
119   }; // 待验证数据,仅供参考。
120   Crypto_DataBlob msgBlob = {
121      .data = reinterpret_cast<uint8_t *>(plainText),
122      .len = sizeof(plainText)
123   };
124
125   uint8_t pubKeyText[] = {
126      0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a,
127      0x81, 0x1c, 0xcf, 0x55, 0x01, 0x82, 0x2d, 0x03, 0x42, 0x00, 0x04, 0x80, 0x5b, 0x78, 0x04, 0xd7,
128      0xcf, 0xc3, 0x99, 0x63, 0xae, 0x88, 0xcd, 0xfc, 0xd6, 0x18, 0xf4, 0x08, 0xe8, 0xe3, 0x68, 0x47,
129      0x4f, 0x44, 0x0e, 0xb2, 0xba, 0x3a, 0xb3, 0x10, 0xf1, 0xc9, 0xd0, 0x84, 0xe2, 0xa4, 0x47, 0xbe,
130      0x72, 0xae, 0xf8, 0x6a, 0xeb, 0x6e, 0x10, 0xab, 0x52, 0x6b, 0x6a, 0x58, 0xc6, 0xb5, 0x78, 0xaa,
131      0x70, 0xe5, 0x58, 0x20, 0x4e, 0x34, 0x42, 0x77, 0x08, 0x27, 0x11,
132   }; // 公钥DER编码数据,仅供参考。
133
134   Crypto_DataBlob keyBlob = {
135      .data = reinterpret_cast<uint8_t *>(pubKeyText),
136      .len = sizeof(pubKeyText)
137   };
138
139   uint8_t signText[] = {
140      0x30, 0x45, 0x02, 0x21, 0x00, 0xf4, 0xe7, 0x9d, 0x35, 0x33, 0xa6, 0x86, 0x2e, 0x2a, 0x97, 0x72,
141      0xc9, 0x46, 0x79, 0x65, 0xca, 0x4a, 0x71, 0x34, 0xca, 0xf7, 0x58, 0xb3, 0x26, 0xa5, 0xdb, 0xfa,
142      0x8b, 0xbe, 0xbf, 0x5f, 0x90, 0x02, 0x20, 0x53, 0xb4, 0x23, 0xb1, 0xe2, 0x8f, 0x2f, 0xe9, 0xc8,
143      0x22, 0xef, 0xab, 0x9b, 0x13, 0x08, 0x75, 0x8e, 0xb1, 0x9c, 0x59, 0xe5, 0xd6, 0x64, 0x35, 0xf5,
144      0xd1, 0xde, 0xfa, 0xfe, 0x80, 0x37, 0x1a,
145   }; // 签名数据,仅供参考。
146
147   Crypto_DataBlob signBlob = {
148      .data = reinterpret_cast<uint8_t *>(signText),
149      .len = sizeof(signText)
150   };
151
152   // keypair
153   OH_Crypto_ErrCode ret = CRYPTO_SUCCESS;
154   ret = OH_CryptoAsymKeyGenerator_Create((const char *)"SM2_256", &keyCtx); // 创建非对称密钥生成器。
155   if (ret != CRYPTO_SUCCESS) {
156      return false;
157   }
158   ret = OH_CryptoAsymKeyGenerator_Convert(keyCtx, CRYPTO_DER, &keyBlob, nullptr, &keyPair); // 将DER格式的公钥编码数据转换为OH_CryptoKeyPair。
159   if (ret != CRYPTO_SUCCESS) {
160      OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
161      return false;
162   }
163   OH_CryptoPubKey *pubKey = OH_CryptoKeyPair_GetPubKey(keyPair);
164   // verify
165   ret = OH_CryptoVerify_Create((const char *)"SM2_256|SM3", &verify); // 创建Verify实例。
166   if (ret != CRYPTO_SUCCESS) {
167      OH_CryptoVerify_Destroy(verify);
168      OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
169      return false;
170   }
171   ret = OH_CryptoVerify_Init(verify, pubKey); // 使用公钥初始化Verify实例。
172   if (ret != CRYPTO_SUCCESS) {
173      OH_CryptoVerify_Destroy(verify);
174      OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
175      return false;
176   }
177   bool res = OH_CryptoVerify_Final(verify, &msgBlob, &signBlob); // 对数据进行验签。
178   if (res != true) {
179      OH_CryptoVerify_Destroy(verify);
180      OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
181      return false;
182   }
183
184   OH_CryptoVerify_Destroy(verify);
185   OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
186   OH_CryptoKeyPair_Destroy(keyPair);
187   return res;
188}
189  ```
190