• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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