1# Signing and Signature Verification with an SM2 Key Pair (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 10For details about the algorithm specifications, see [SM2](crypto-sign-sig-verify-overview.md#sm2). 11 12## Adding the Dynamic Library in the CMake Script 13```txt 14target_link_libraries(entry PUBLIC libohcrypto.so) 15``` 16 17## Signing Data 181. Call [OH_CryptoSign_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptosign_create) with the string parameter **'SM2_256|SM3'** to create a **Sign** instance. The key type is **SM2_256**, and MD algorithm is **SM3**. 19 202. Call [OH_CryptoSign_Init](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptosign_init) to initialize the **Sign** instance using [OH_CryptoPrivKey](../../reference/apis-crypto-architecture-kit/capi-cryptoasymkeyapi-oh-cryptoprivkey.md). 21 223. Call [OH_CryptoSign_Update](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptosign_update) to pass in the data to be signed. Currently, the amount of data to be passed in by a single **update** is not limited. You can determine how to pass in data based on the data volume. If the data size is small, you can simply call **OH_CryptoSign_Final** to pass in the full data. 23 244. Call [OH_CryptoSign_Final](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptosign_final) to obtain the signed data. 25 265. Call [OH_CryptoSign_Destroy](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptosign_destroy) to free the memory. 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## Verifying the Signature 96 971. Call [OH_CryptoVerify_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_create) with the string parameter **'SM2_256|SM3'** to create a **Verify** instance. The key type is **SM2_256**, and MD algorithm is **SM3**. 98 992. Call [OH_CryptoVerify_Init](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_init) to initialize the **Verify** instance by using the public key (**OH_CryptoPubKey**). 100 1013. Call [OH_CryptoVerify_Update](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_update) to pass in the data to be verified. Currently, the amount of data to be passed in by a single **OH_CryptoVerify_Update** is not limited. You can determine how to pass in data based on the data volume. If a small amount of data is to be verified, you can call **OH_CryptoVerify_Final** immediately after **OH_CryptoVerify_Init()**. 102 1034. Call [OH_CryptoVerify_Final](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_final) to verify the signature. 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 }; // Data to be verified, for reference only. 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 }; // Public key in DER format, for reference only. 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 }; // Signature data, for reference only. 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); // Create an asymmetric key generator. 155 if (ret != CRYPTO_SUCCESS) { 156 return false; 157 } 158 ret = OH_CryptoAsymKeyGenerator_Convert(keyCtx, CRYPTO_DER, &keyBlob, nullptr, &keyPair); // Convert the public key in DER format to 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); // Create a Verify instance. 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); // Use the public key to initialize the Verify instance. 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); // Verify the signature of the data. 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