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