1# Generating an Asymmetric Key Pair Based on Key Parameters (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 10This topic walks you through on how to generate an RSA, an ECC, and an SM2 asymmetric key pair (**KeyPair**) based on the specified key parameters and obtain the key parameter properties. 11 12The **KeyPair** object created can be used for subsequent operations, such as encryption and decryption. The obtained key parameter properties can be used for key storage and transfer. 13 14## Generating an RSA Key Pair Based on Key Parameters 15 16For details about the algorithm specifications, see [RSA](crypto-asym-key-generation-conversion-spec.md#rsa). 17 181. Call [OH_CryptoAsymKeySpec_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-key-h.md#oh_cryptoasymkeyspec_create) to set the algorithm name to **RSA** and the key parameter type to **CRYPTO_ASYM_KEY_KEY_PAIR_SPEC** to create a parameter object (**keySpec**). 19 202. Specify the RSA key pair data (**pk**, **sk**, and **n**) of the uint8_t type and encapsulate them into [Crypto_DataBlob](../../reference/apis-crypto-architecture-kit/capi-cryptocommonapi-crypto-datablob.md). 21 223. Call [OH_CryptoAsymKeySpec_SetParam](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-key-h.md#oh_cryptoasymkeyspec_setparam) to set the parameter types to **CRYPTO_RSA_E_DATABLOB (pk)**, **CRYPTO_RSA_D_DATABLOB (sk)**, and **CRYPTO_RSA_N_DATABLOB (n)** respectively, and pass the encapsulated [Crypto_DataBlob](../../reference/apis-crypto-architecture-kit/capi-cryptocommonapi-crypto-datablob.md) in sequence to set the parameter object (**keySpec**). 23 24 > **NOTE** 25 > The values of **pk**, **sk**, and **n** must be positive numbers entered in big-endian mode. 26 274. Call [OH_CryptoAsymKeyGeneratorWithSpec_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-key-h.md#oh_cryptoasymkeygeneratorwithspec_create) to pass the parameter object (**keySpec**) and create an asymmetric key generator (**generatorSpec**). 28 295. Call [OH_CryptoAsymKeyGeneratorWithSpec_GenKeyPair](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-key-h.md#oh_cryptoasymkeygeneratorwithspec_genkeypair) to generate an RSA key pair (**keyPair**). 30 316. Pass the private key and public key in the key pair, and call [OH_CryptoPrivKey_GetParam](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-key-h.md#oh_cryptoprivkey_getparam) and [OH_CryptoPubKey_GetParam](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-key-h.md#oh_cryptopubkey_getparam) to obtain the key parameters of the private key and public key in the RSA algorithm. 32 33```C++ 34#include "CryptoArchitectureKit/crypto_architecture_kit.h" 35#include <string> 36 37static OH_Crypto_ErrCode GetRsaKeyParams(OH_CryptoKeyPair *keyCtx, Crypto_DataBlob *pubKeyData, 38 Crypto_DataBlob *dataN) 39{ 40 OH_CryptoPubKey *pubKey = OH_CryptoKeyPair_GetPubKey(keyCtx); 41 if (pubKey == nullptr) { 42 return CRYPTO_OPERTION_ERROR; 43 } 44 OH_Crypto_ErrCode ret = OH_CryptoPubKey_GetParam(pubKey, CRYPTO_RSA_E_DATABLOB, pubKeyData); 45 if (ret != CRYPTO_SUCCESS) { 46 return ret; 47 } 48 return OH_CryptoPubKey_GetParam(pubKey, CRYPTO_RSA_N_DATABLOB, dataN); 49} 50 51static void FreeRsaKeyParams(Crypto_DataBlob *pubKeyData, Crypto_DataBlob *dataN) 52{ 53 OH_Crypto_FreeDataBlob(pubKeyData); 54 OH_Crypto_FreeDataBlob(dataN); 55} 56 57size_t ConvertHex(uint8_t* dest, size_t count, const char* src) 58{ 59 size_t i; 60 int value; 61 62 for (i = 0; i < count && sscanf(src + i * 2, "%2x", &value) == 1; i++) { 63 dest[i] = value; 64 } 65 return i; 66} 67 68static OH_Crypto_ErrCode doTestRsaGenKeyPairBySpec() 69{ 70 std::string nStr = "9260d0750ae117eee55c3f3deaba74917521a262ee76007cdf8a56755ad73a1598a1408410a01434c3f5bc54a88b57fa19fc4328daea0750a4c44e88cff3b2382621b80f670464433e4336e6d003e8cd65bff211da144b88291c2259a00a72b711c116ef7686e8fee34e4d933c868187bdc26f7be071493c86f7a5941c3510806ad67b0f94d88f5cf5c02a092821d8626e8932b65c5bd8c92049c210932b7afa7ac59c0e886ae5c1edb00d8ce2c57633db26bd6639bff73cee82be9275c402b4cf2a4388da8cf8c64eefe1c5a0f5ab8057c39fa5c0589c3e253f0960332300f94bea44877b588e1edbde97cf2360727a09b775262d7ee552b3319b9266f05a25"; 71 std::string eStr = "010001"; 72 uint8_t n[1024] = {}; 73 uint8_t e[20] = {}; 74 size_t nLen = ConvertHex(n, nStr.size() / 2, nStr.c_str()); 75 size_t eLen = ConvertHex(e, eStr.size() / 2, eStr.c_str()); 76 Crypto_DataBlob nData = {.data = n, .len = nLen}; 77 Crypto_DataBlob eData = {.data = e, .len = eLen}; 78 79 OH_CryptoAsymKeySpec *keySpec = nullptr; 80 OH_Crypto_ErrCode ret = OH_CryptoAsymKeySpec_Create("RSA", CRYPTO_ASYM_KEY_PUBLIC_KEY_SPEC, &keySpec); 81 if (ret != CRYPTO_SUCCESS) { 82 return ret; 83 } 84 ret = OH_CryptoAsymKeySpec_SetParam(keySpec, CRYPTO_RSA_E_DATABLOB, &eData); 85 if (ret != CRYPTO_SUCCESS) { 86 OH_CryptoAsymKeySpec_Destroy(keySpec); 87 return ret; 88 } 89 ret = OH_CryptoAsymKeySpec_SetParam(keySpec, CRYPTO_RSA_N_DATABLOB, &nData); 90 if (ret != CRYPTO_SUCCESS) { 91 OH_CryptoAsymKeySpec_Destroy(keySpec); 92 return ret; 93 } 94 95 OH_CryptoAsymKeyGeneratorWithSpec *generatorSpec = nullptr; 96 ret = OH_CryptoAsymKeyGeneratorWithSpec_Create(keySpec, &generatorSpec); 97 if (ret != CRYPTO_SUCCESS) { 98 OH_CryptoAsymKeySpec_Destroy(keySpec); 99 return ret; 100 } 101 OH_CryptoKeyPair *keyPair = nullptr; 102 ret = OH_CryptoAsymKeyGeneratorWithSpec_GenKeyPair(generatorSpec, &keyPair); 103 if (ret != CRYPTO_SUCCESS) { 104 OH_CryptoAsymKeyGeneratorWithSpec_Destroy(generatorSpec); 105 OH_CryptoAsymKeySpec_Destroy(keySpec); 106 return ret; 107 } 108 109 Crypto_DataBlob dataE = {.data = nullptr, .len = 0}; 110 Crypto_DataBlob dataN = {.data = nullptr, .len = 0}; 111 ret = GetRsaKeyParams(keyPair, &dataE, &dataN); 112 if (ret != CRYPTO_SUCCESS) { 113 FreeRsaKeyParams(&dataE, &dataN); 114 OH_CryptoKeyPair_Destroy(keyPair); 115 OH_CryptoAsymKeyGeneratorWithSpec_Destroy(generatorSpec); 116 OH_CryptoAsymKeySpec_Destroy(keySpec); 117 return ret; 118 } 119 FreeRsaKeyParams(&dataE, &dataN); 120 OH_CryptoKeyPair_Destroy(keyPair); 121 OH_CryptoAsymKeyGeneratorWithSpec_Destroy(generatorSpec); 122 OH_CryptoAsymKeySpec_Destroy(keySpec); 123 return ret; 124} 125``` 126 127## Generating an ECC Key Pair Based on Key Parameters 128 129For details about the algorithm specifications, see [ECC](crypto-asym-key-generation-conversion-spec.md#ecc). 130 1311. Call [OH_CryptoAsymKeySpec_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-key-h.md#oh_cryptoasymkeyspec_create) to set the algorithm name to **ECC** and the key parameter type to **CRYPTO_ASYM_KEY_COMMON_PARAMS_SPEC** to create a parameter object (**keySpec**). 132 1332. Specify the common parameters (**p**, **a**, **b**, **gx**, **gy**, **n**, and **h**) contained in the ECC public and private keys of the uint8_t type and encapsulate them into [Crypto_DataBlob](../../reference/apis-crypto-architecture-kit/capi-cryptocommonapi-crypto-datablob.md). 134 1353. Call [OH_CryptoAsymKeySpec_SetParam](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-key-h.md#oh_cryptoasymkeyspec_setparam) to set the parameter types to **CRYPTO_ECC_FP_P_DATABLOB (p)**, **CRYPTO_ECC_A_DATABLOB (a)**, **CRYPTO_ECC_B_DATABLOB (b)**, **CRYPTO_ECC_G_X_DATABLOB (gx)**, **CRYPTO_ECC_G_Y_DATABLOB (gy)**, **CRYPTO_ECC_N_DATABLOB (n)**, and **CRYPTO_ECC_H_INT (h)**, respectively, and pass the encapsulated [Crypto_DataBlob](../../reference/apis-crypto-architecture-kit/capi-cryptocommonapi-crypto-datablob.md) in sequence to the parameter object (**keySpec**). 136 137 > **NOTE** 138 > **p**, **a**, **b**, **gx**, **gy**, **n**, and **h** must be positive numbers entered in big-endian mode. 139 1404. Call [OH_CryptoAsymKeyGeneratorWithSpec_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-key-h.md#oh_cryptoasymkeygeneratorwithspec_create) to pass the parameter object (**keySpec**) and create an asymmetric key generator (**generatorSpec**). 141 1425. Call [OH_CryptoAsymKeyGeneratorWithSpec_GenKeyPair](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-key-h.md#oh_cryptoasymkeygeneratorwithspec_genkeypair) to generate an ECC key pair (**keyPair**). 143 1446. Pass the private key and public key in the key pair, and call [OH_CryptoPrivKey_GetParam](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-key-h.md#oh_cryptoprivkey_getparam) and [OH_CryptoPubKey_GetParam](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-key-h.md#oh_cryptopubkey_getparam) to obtain the key parameters of the private key and public key in the ECC algorithm. 145 146 147```C++ 148#include "CryptoArchitectureKit/crypto_architecture_kit.h" 149#include <string> 150 151static OH_Crypto_ErrCode GetEccKeyParams(OH_CryptoKeyPair *keyCtx, Crypto_DataBlob *pubKeyXData, 152 Crypto_DataBlob *pubKeyYData, Crypto_DataBlob *privKeyData) 153{ 154 OH_CryptoPubKey *pubKey = OH_CryptoKeyPair_GetPubKey(keyCtx); 155 if (pubKey == nullptr) { 156 return CRYPTO_OPERTION_ERROR; 157 } 158 OH_Crypto_ErrCode ret = OH_CryptoPubKey_GetParam(pubKey, CRYPTO_ECC_PK_X_DATABLOB, pubKeyXData); 159 if (ret != CRYPTO_SUCCESS) { 160 return ret; 161 } 162 ret = OH_CryptoPubKey_GetParam(pubKey, CRYPTO_ECC_PK_Y_DATABLOB, pubKeyYData); 163 if (ret != CRYPTO_SUCCESS) { 164 return ret; 165 } 166 167 OH_CryptoPrivKey *privKey = OH_CryptoKeyPair_GetPrivKey(keyCtx); 168 if (privKey == nullptr) { 169 return CRYPTO_OPERTION_ERROR; 170 } 171 ret = OH_CryptoPrivKey_GetParam(privKey, CRYPTO_ECC_SK_DATABLOB, privKeyData); 172 return ret; 173} 174 175static void FreeEccKeyParams(Crypto_DataBlob *pubKeyXData, Crypto_DataBlob *pubKeyYData, Crypto_DataBlob *privKeyData) 176{ 177 OH_Crypto_FreeDataBlob(pubKeyXData); 178 OH_Crypto_FreeDataBlob(pubKeyYData); 179 OH_Crypto_FreeDataBlob(privKeyData); 180} 181 182static OH_Crypto_ErrCode GetEccCommonParams(OH_CryptoKeyPair *keyCtx, Crypto_DataBlob *pData, 183 Crypto_DataBlob *aData, Crypto_DataBlob *bData, Crypto_DataBlob *gxData, 184 Crypto_DataBlob *gyData, Crypto_DataBlob *nData, Crypto_DataBlob *hData) 185{ 186 OH_CryptoPrivKey *privKey = OH_CryptoKeyPair_GetPrivKey(keyCtx); 187 if (privKey == nullptr) { 188 return CRYPTO_OPERTION_ERROR; 189 } 190 OH_Crypto_ErrCode ret = OH_CryptoPrivKey_GetParam(privKey, CRYPTO_ECC_FP_P_DATABLOB, pData); 191 if (ret != CRYPTO_SUCCESS) { 192 return ret; 193 } 194 ret = OH_CryptoPrivKey_GetParam(privKey, CRYPTO_ECC_A_DATABLOB, aData); 195 if (ret != CRYPTO_SUCCESS) { 196 return ret; 197 } 198 ret = OH_CryptoPrivKey_GetParam(privKey, CRYPTO_ECC_B_DATABLOB, bData); 199 if (ret != CRYPTO_SUCCESS) { 200 return ret; 201 } 202 ret = OH_CryptoPrivKey_GetParam(privKey, CRYPTO_ECC_G_X_DATABLOB, gxData); 203 if (ret != CRYPTO_SUCCESS) { 204 return ret; 205 } 206 ret = OH_CryptoPrivKey_GetParam(privKey, CRYPTO_ECC_G_Y_DATABLOB, gyData); 207 if (ret != CRYPTO_SUCCESS) { 208 return ret; 209 } 210 ret = OH_CryptoPrivKey_GetParam(privKey, CRYPTO_ECC_N_DATABLOB, nData); 211 if (ret != CRYPTO_SUCCESS) { 212 return ret; 213 } 214 ret = OH_CryptoPrivKey_GetParam(privKey, CRYPTO_ECC_H_INT, hData); 215 if (ret != CRYPTO_SUCCESS) { 216 return ret; 217 } 218 return ret; 219} 220 221static void FreeEccCommonParams(Crypto_DataBlob *pData, Crypto_DataBlob *aData, Crypto_DataBlob *bData, 222 Crypto_DataBlob *gxData, Crypto_DataBlob *gyData, Crypto_DataBlob *nData, 223 Crypto_DataBlob *hData) 224{ 225 OH_Crypto_FreeDataBlob(pData); 226 OH_Crypto_FreeDataBlob(aData); 227 OH_Crypto_FreeDataBlob(bData); 228 OH_Crypto_FreeDataBlob(gxData); 229 OH_Crypto_FreeDataBlob(gyData); 230 OH_Crypto_FreeDataBlob(nData); 231 OH_Crypto_FreeDataBlob(hData); 232} 233 234size_t ConvertHex(uint8_t* dest, size_t count, const char* src) 235{ 236 size_t i; 237 int value; 238 239 for (i = 0; i < count && sscanf(src + i * 2, "%2x", &value) == 1; i++) { 240 dest[i] = value; 241 } 242 return i; 243} 244 245static OH_Crypto_ErrCode doTestEccGenKeyPairBySpec() 246{ 247 std::string pStr = "ffffffffffffffffffffffffffffffff000000000000000000000001"; 248 std::string gxStr = "b70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21"; 249 std::string gyStr = "bd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34"; 250 std::string aStr = "fffffffffffffffffffffffffffffffefffffffffffffffffffffffe"; 251 std::string bStr = "b4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4"; 252 std::string nStr = "ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d"; 253 uint8_t p[256] = {}; 254 uint8_t gx[256] = {}; 255 uint8_t gy[256] = {}; 256 uint8_t a[256] = {}; 257 uint8_t b[256] = {}; 258 uint8_t n[256] = {}; 259 uint8_t h[] = {0x00, 0x00, 0x00, 0x01}; // Digit 1 in big-endian mode 260 size_t pLen = ConvertHex(p, pStr.size() / 2, pStr.c_str()); 261 size_t gxLen = ConvertHex(gx, gxStr.size() / 2, gxStr.c_str()); 262 size_t gyLen = ConvertHex(gy, gyStr.size() / 2, gyStr.c_str()); 263 size_t aLen = ConvertHex(a, aStr.size() / 2, aStr.c_str()); 264 size_t bLen = ConvertHex(b, bStr.size() / 2, bStr.c_str()); 265 size_t nLen = ConvertHex(n, nStr.size() / 2, nStr.c_str()); 266 Crypto_DataBlob pData = {.data = p, .len = pLen}; 267 Crypto_DataBlob aData = {.data = a, .len = aLen}; 268 Crypto_DataBlob bData = {.data = b, .len = bLen}; 269 Crypto_DataBlob gxData = {.data = gx, .len = gxLen}; 270 Crypto_DataBlob gyData = {.data = gy, .len = gyLen}; 271 Crypto_DataBlob nData = {.data = n, .len = nLen}; 272 Crypto_DataBlob hData = {.data = h, .len = sizeof(h)}; 273 274 OH_CryptoAsymKeySpec *keySpec = nullptr; 275 OH_Crypto_ErrCode ret = OH_CryptoAsymKeySpec_Create("ECC", CRYPTO_ASYM_KEY_COMMON_PARAMS_SPEC, &keySpec); 276 if (ret != CRYPTO_SUCCESS) { 277 return ret; 278 } 279 ret = OH_CryptoAsymKeySpec_SetParam(keySpec, CRYPTO_ECC_FP_P_DATABLOB, &pData); 280 if (ret != CRYPTO_SUCCESS) { 281 OH_CryptoAsymKeySpec_Destroy(keySpec); 282 return ret; 283 } 284 ret = OH_CryptoAsymKeySpec_SetParam(keySpec, CRYPTO_ECC_A_DATABLOB, &aData); 285 if (ret != CRYPTO_SUCCESS) { 286 OH_CryptoAsymKeySpec_Destroy(keySpec); 287 return ret; 288 } 289 ret = OH_CryptoAsymKeySpec_SetParam(keySpec, CRYPTO_ECC_B_DATABLOB, &bData); 290 if (ret != CRYPTO_SUCCESS) { 291 OH_CryptoAsymKeySpec_Destroy(keySpec); 292 return ret; 293 } 294 ret = OH_CryptoAsymKeySpec_SetParam(keySpec, CRYPTO_ECC_G_X_DATABLOB, &gxData); 295 if (ret != CRYPTO_SUCCESS) { 296 OH_CryptoAsymKeySpec_Destroy(keySpec); 297 return ret; 298 } 299 ret = OH_CryptoAsymKeySpec_SetParam(keySpec, CRYPTO_ECC_G_Y_DATABLOB, &gyData); 300 if (ret != CRYPTO_SUCCESS) { 301 OH_CryptoAsymKeySpec_Destroy(keySpec); 302 return ret; 303 } 304 ret = OH_CryptoAsymKeySpec_SetParam(keySpec, CRYPTO_ECC_N_DATABLOB, &nData); 305 if (ret != CRYPTO_SUCCESS) { 306 OH_CryptoAsymKeySpec_Destroy(keySpec); 307 return ret; 308 } 309 ret = OH_CryptoAsymKeySpec_SetParam(keySpec, CRYPTO_ECC_H_INT, &hData); 310 if (ret != CRYPTO_SUCCESS) { 311 OH_CryptoAsymKeySpec_Destroy(keySpec); 312 return ret; 313 } 314 315 OH_CryptoAsymKeyGeneratorWithSpec *generatorSpec = nullptr; 316 ret = OH_CryptoAsymKeyGeneratorWithSpec_Create(keySpec, &generatorSpec); 317 if (ret != CRYPTO_SUCCESS) { 318 OH_CryptoAsymKeySpec_Destroy(keySpec); 319 return ret; 320 } 321 OH_CryptoKeyPair *keyPair = nullptr; 322 ret = OH_CryptoAsymKeyGeneratorWithSpec_GenKeyPair(generatorSpec, &keyPair); 323 if (ret != CRYPTO_SUCCESS) { 324 OH_CryptoAsymKeyGeneratorWithSpec_Destroy(generatorSpec); 325 OH_CryptoAsymKeySpec_Destroy(keySpec); 326 return ret; 327 } 328 329 Crypto_DataBlob dataPkX = {.data = nullptr, .len = 0}; 330 Crypto_DataBlob dataPkY = {.data = nullptr, .len = 0}; 331 Crypto_DataBlob dataSk = {.data = nullptr, .len = 0}; 332 ret = GetEccKeyParams(keyPair, &dataPkX, &dataPkY, &dataSk); 333 if (ret != CRYPTO_SUCCESS) { 334 FreeEccKeyParams(&dataPkX, &dataPkY, &dataSk); 335 OH_CryptoKeyPair_Destroy(keyPair); 336 OH_CryptoAsymKeySpec_Destroy(keySpec); 337 OH_CryptoAsymKeyGeneratorWithSpec_Destroy(generatorSpec); 338 return ret; 339 } 340 FreeEccKeyParams(&dataPkX, &dataPkY, &dataSk); 341 Crypto_DataBlob dataP = {.data = nullptr, .len = 0}; 342 Crypto_DataBlob dataA = {.data = nullptr, .len = 0}; 343 Crypto_DataBlob dataB = {.data = nullptr, .len = 0}; 344 Crypto_DataBlob dataGx = {.data = nullptr, .len = 0}; 345 Crypto_DataBlob dataGy = {.data = nullptr, .len = 0}; 346 Crypto_DataBlob dataN = {.data = nullptr, .len = 0}; 347 Crypto_DataBlob dataH = {.data = nullptr, .len = 0}; 348 ret = GetEccCommonParams(keyPair, &dataP, &dataA, &dataB, &dataGx, &dataGy, &dataN, &dataH); 349 if (ret != CRYPTO_SUCCESS) { 350 FreeEccCommonParams(&dataP, &dataA, &dataB, &dataGx, &dataGy, &dataN, &dataH); 351 OH_CryptoKeyPair_Destroy(keyPair); 352 OH_CryptoAsymKeySpec_Destroy(keySpec); 353 OH_CryptoAsymKeyGeneratorWithSpec_Destroy(generatorSpec); 354 return ret; 355 } 356 FreeEccCommonParams(&dataP, &dataA, &dataB, &dataGx, &dataGy, &dataN, &dataH); 357 OH_CryptoKeyPair_Destroy(keyPair); 358 OH_CryptoAsymKeySpec_Destroy(keySpec); 359 OH_CryptoAsymKeyGeneratorWithSpec_Destroy(generatorSpec); 360 return ret; 361} 362``` 363 364## Generating an SM2 Key Pair Based on the Elliptic Curve Name 365 366For details about the algorithm specifications, see [SM2](crypto-asym-key-generation-conversion-spec.md#sm2). 367 3681. Call [OH_CryptoAsymKeySpec_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-key-h.md#oh_cryptoasymkeyspec_create) to set the algorithm name to **SM2** and the key parameter type to **CRYPTO_ASYM_KEY_KEY_PAIR_SPEC** to create a key parameter object (**keySpec**). 369 3702. Call [OH_CryptoAsymKeySpec_GenEcCommonParamsSpec](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-key-h.md#oh_cryptoasymkeyspec_geneccommonparamsspec) to generate an SM2 common parameter object (**sm2CommonSpec**) with the curve name set to **NID_sm2**. 371 3723. Call [OH_CryptoAsymKeySpec_SetCommonParamsSpec](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-key-h.md#oh_cryptoasymkeyspec_setcommonparamsspec) to set the generated **sm2CommonSpec** to the key parameter object (**keySpec**). 373 3744. Specify the SM2 key pair data (**pkx**, **pky**, and **sk**) of the uint8_t type and encapsulate them into [Crypto_DataBlob](../../reference/apis-crypto-architecture-kit/capi-cryptocommonapi-crypto-datablob.md). 375 3765. Call [OH_CryptoAsymKeySpec_SetParam](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-key-h.md#oh_cryptoasymkeyspec_setparam) to set the parameter types to **CRYPTO_ECC_PK_X_DATABLOB (pkx)**, **CRYPTO_ECC_PK_Y_DATABLOB (pky)**, and **CRYPTO_ECC_SK_DATABLOB (sk)** respectively, and pass the encapsulated [Crypto_DataBlob](../../reference/apis-crypto-architecture-kit/capi-cryptocommonapi-crypto-datablob.md) in sequence to set the parameter object (**keySpec**). 377 378 > **NOTE** 379 > The values of **pkx**, **pky**, and **sk** must be positive numbers entered in big-endian mode. 380 3816. Call [OH_CryptoAsymKeyGeneratorWithSpec_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-key-h.md#oh_cryptoasymkeygeneratorwithspec_create) to pass the parameter object (**keySpec**) and create an asymmetric key generator (**generatorSpec**). 382 3837. Call [OH_CryptoAsymKeyGeneratorWithSpec_GenKeyPair](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-key-h.md#oh_cryptoasymkeygeneratorwithspec_genkeypair) to generate an SM2 key pair (**keyPair**). 384 3858. Pass the private key and public key in the key pair, and call [OH_CryptoPrivKey_GetParam](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-key-h.md#oh_cryptoprivkey_getparam) and [OH_CryptoPubKey_GetParam](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-key-h.md#oh_cryptopubkey_getparam) to obtain the key parameters of the private key and public key in the SM2 algorithm. 386 387```C++ 388#include "CryptoArchitectureKit/crypto_architecture_kit.h" 389#include <string> 390 391size_t ConvertHex(uint8_t* dest, size_t count, const char* src) 392{ 393 size_t i; 394 int value; 395 396 for (i = 0; i < count && sscanf(src + i * 2, "%2x", &value) == 1; i++) { 397 dest[i] = value; 398 } 399 return i; 400} 401 402static OH_Crypto_ErrCode doTestSm2GenKeyPairBySpec() 403{ 404 std::string pkXStr = "67F3B850BDC0BA5D3A29D8A0883C4B17612AB84F87F18E28F77D824A115C02C4"; 405 std::string pkYStr = "D48966CE754BBBEDD6501A1385E1B205C186E926ADED44287145E8897D4B2071"; 406 std::string skStr = "6330B599ECD23ABDC74B9A5B7B5E00E553005F72743101C5FAB83AEB579B7074"; 407 uint8_t pkX[256] = {}; 408 uint8_t pkY[256] = {}; 409 uint8_t sk[256] = {}; 410 size_t pkXLen = ConvertHex(pkX, pkXStr.size() / 2, pkXStr.c_str()); 411 size_t pkYLen = ConvertHex(pkY, pkYStr.size() / 2, pkYStr.c_str()); 412 size_t skLen = ConvertHex(sk, skStr.size() / 2, skStr.c_str()); 413 Crypto_DataBlob pkXData = {.data = pkX, .len = pkXLen}; 414 Crypto_DataBlob pkYData = {.data = pkY, .len = pkYLen}; 415 Crypto_DataBlob skData = {.data = sk, .len = skLen}; 416 417 OH_CryptoAsymKeySpec *keySpec = nullptr; 418 OH_Crypto_ErrCode ret = OH_CryptoAsymKeySpec_Create("SM2", CRYPTO_ASYM_KEY_KEY_PAIR_SPEC, &keySpec); 419 if (ret != CRYPTO_SUCCESS) { 420 return ret; 421 } 422 OH_CryptoAsymKeySpec *sm2CommonSpec = nullptr; 423 ret = OH_CryptoAsymKeySpec_GenEcCommonParamsSpec("NID_sm2", &sm2CommonSpec); 424 if (ret != CRYPTO_SUCCESS) { 425 OH_CryptoAsymKeySpec_Destroy(keySpec); 426 return ret; 427 } 428 ret = OH_CryptoAsymKeySpec_SetCommonParamsSpec(keySpec, sm2CommonSpec); 429 if (ret != CRYPTO_SUCCESS) { 430 OH_CryptoAsymKeySpec_Destroy(sm2CommonSpec); 431 OH_CryptoAsymKeySpec_Destroy(keySpec); 432 return ret; 433 } 434 ret = OH_CryptoAsymKeySpec_SetParam(keySpec, CRYPTO_ECC_PK_X_DATABLOB, &pkXData); 435 if (ret != CRYPTO_SUCCESS) { 436 OH_CryptoAsymKeySpec_Destroy(sm2CommonSpec); 437 OH_CryptoAsymKeySpec_Destroy(keySpec); 438 return ret; 439 } 440 ret = OH_CryptoAsymKeySpec_SetParam(keySpec, CRYPTO_ECC_PK_Y_DATABLOB, &pkYData); 441 if (ret != CRYPTO_SUCCESS) { 442 OH_CryptoAsymKeySpec_Destroy(sm2CommonSpec); 443 OH_CryptoAsymKeySpec_Destroy(keySpec); 444 return ret; 445 } 446 ret = OH_CryptoAsymKeySpec_SetParam(keySpec, CRYPTO_ECC_SK_DATABLOB, &skData); 447 if (ret != CRYPTO_SUCCESS) { 448 OH_CryptoAsymKeySpec_Destroy(sm2CommonSpec); 449 OH_CryptoAsymKeySpec_Destroy(keySpec); 450 return ret; 451 } 452 453 OH_CryptoAsymKeyGeneratorWithSpec *generatorSpec = nullptr; 454 ret = OH_CryptoAsymKeyGeneratorWithSpec_Create(keySpec, &generatorSpec); 455 if (ret != CRYPTO_SUCCESS) { 456 OH_CryptoAsymKeySpec_Destroy(sm2CommonSpec); 457 OH_CryptoAsymKeySpec_Destroy(keySpec); 458 return ret; 459 } 460 OH_CryptoKeyPair *keyPair = nullptr; 461 ret = OH_CryptoAsymKeyGeneratorWithSpec_GenKeyPair(generatorSpec, &keyPair); 462 if (ret != CRYPTO_SUCCESS) { 463 OH_CryptoAsymKeyGeneratorWithSpec_Destroy(generatorSpec); 464 OH_CryptoAsymKeySpec_Destroy(sm2CommonSpec); 465 OH_CryptoAsymKeySpec_Destroy(keySpec); 466 return ret; 467 } 468 469 Crypto_DataBlob dataPkX = {.data = nullptr, .len = 0}; 470 Crypto_DataBlob dataPkY = {.data = nullptr, .len = 0}; 471 Crypto_DataBlob dataSk = {.data = nullptr, .len = 0}; 472 ret = GetEccKeyParams(keyPair, &dataPkX, &dataPkY, &dataSk); 473 if (ret != CRYPTO_SUCCESS) { 474 FreeEccKeyParams(&dataPkX, &dataPkY, &dataSk); 475 OH_CryptoKeyPair_Destroy(keyPair); 476 OH_CryptoAsymKeyGeneratorWithSpec_Destroy(generatorSpec); 477 OH_CryptoAsymKeySpec_Destroy(sm2CommonSpec); 478 OH_CryptoAsymKeySpec_Destroy(keySpec); 479 return ret; 480 } 481 FreeEccKeyParams(&dataPkX, &dataPkY, &dataSk); 482 OH_CryptoKeyPair_Destroy(keyPair); 483 OH_CryptoAsymKeyGeneratorWithSpec_Destroy(generatorSpec); 484 OH_CryptoAsymKeySpec_Destroy(sm2CommonSpec); 485 OH_CryptoAsymKeySpec_Destroy(keySpec); 486 return ret; 487} 488``` 489