• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 指定密钥参数生成非对称密钥对(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以RSA、ECC、SM2为例,根据指定的密钥参数,生成非对称密钥对(KeyPair),并获取密钥参数属性。
11
12该对象可用于后续的加解密等操作。获取的密钥参数属性可用于存储或运输。
13
14## 指定密钥参数生成RSA密钥对
15
16对应的算法规格请查看[非对称密钥生成和转换规格:RSA](crypto-asym-key-generation-conversion-spec.md#rsa)。
17
181. 调用[OH_CryptoAsymKeySpec_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-key-h.md#oh_cryptoasymkeyspec_create),指定算法名为"RSA", 密钥参数类型为CRYPTO_ASYM_KEY_KEY_PAIR_SPEC,创建参数对象(keySpec)。
19
202. 指定uint8_t类型的RSA密钥对数据(pk、sk、n),分别封装成[Crypto_DataBlob](../../reference/apis-crypto-architecture-kit/capi-cryptocommonapi-crypto-datablob.md)。
21
223. 调用[OH_CryptoAsymKeySpec_SetParam](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-key-h.md#oh_cryptoasymkeyspec_setparam),指定参数类型分别为CRYPTO_RSA_E_DATABLOB(pk)、CRYPTO_RSA_D_DATABLOB(sk)、CRYPTO_RSA_N_DATABLOB(n), 依次传入封装后的[Crypto_DataBlob](../../reference/apis-crypto-architecture-kit/capi-cryptocommonapi-crypto-datablob.md),设置参数对象(keySpec)。
23
24   > **注意:**
25   > pk、sk、n均要以大端模式输入,且必须为正数。
26
274. 调用[OH_CryptoAsymKeyGeneratorWithSpec_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-key-h.md#oh_cryptoasymkeygeneratorwithspec_create),将参数对象(keySpec)传入,创建非对称密钥生成器(generatorSpec)。
28
295. 调用[OH_CryptoAsymKeyGeneratorWithSpec_GenKeyPair](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-key-h.md#oh_cryptoasymkeygeneratorwithspec_genkeypair),生成RSA密钥对(keyPair)。
30
316. 分别传入密钥对中的私钥和公钥,调用[OH_CryptoPrivKey_GetParam](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-key-h.md#oh_cryptoprivkey_getparam)和[OH_CryptoPubKey_GetParam](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-key-h.md#oh_cryptopubkey_getparam),获取RSA算法中私钥和公钥的各种密钥参数。
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## 指定密钥参数生成ECC密钥对
128
129对应的算法规格请查看[非对称密钥生成和转换规格:ECC](crypto-asym-key-generation-conversion-spec.md#ecc)。
130
1311. 调用[OH_CryptoAsymKeySpec_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-key-h.md#oh_cryptoasymkeyspec_create),指定算法名为"ECC", 密钥参数类型为CRYPTO_ASYM_KEY_COMMON_PARAMS_SPEC,创建参数对象(keySpec)。
132
1332. 指定uint8_t类型的ECC公私钥包含的公共参数(p、a、b、gx、gy、n、h),分别封装成[Crypto_DataBlob](../../reference/apis-crypto-architecture-kit/capi-cryptocommonapi-crypto-datablob.md)。
134
1353. 调用[OH_CryptoAsymKeySpec_SetParam](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-key-h.md#oh_cryptoasymkeyspec_setparam),指定参数类型分别为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)、CRYPTO_ECC_H_INT(h), 依次传入封装后的[Crypto_DataBlob](../../reference/apis-crypto-architecture-kit/capi-cryptocommonapi-crypto-datablob.md),设置到参数对象(keySpec)。
136
137   > **注意:**
138   > p、a、b、gx、gy、n、h均要以大端模式输入,且必须为正数。
139
1404. 调用[OH_CryptoAsymKeyGeneratorWithSpec_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-key-h.md#oh_cryptoasymkeygeneratorwithspec_create),将参数对象(keySpec)传入,创建非对称密钥生成器(generatorSpec)。
141
1425. 调用[OH_CryptoAsymKeyGeneratorWithSpec_GenKeyPair](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-key-h.md#oh_cryptoasymkeygeneratorwithspec_genkeypair),生成ECC密钥对(keyPair)。
143
1446. 分别传入密钥对中的私钥和公钥,调用[OH_CryptoPrivKey_GetParam](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-key-h.md#oh_cryptoprivkey_getparam)和[OH_CryptoPubKey_GetParam](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-key-h.md#oh_cryptopubkey_getparam),获取ECC算法中私钥和公钥的各种密钥参数。
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}; // 1 大端序
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## 根据椭圆曲线名生成SM2密钥对
365
366对应的算法规格请查看[非对称密钥生成和转换规格:SM2](crypto-asym-key-generation-conversion-spec.md#sm2)。
367
3681. 调用[OH_CryptoAsymKeySpec_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-key-h.md#oh_cryptoasymkeyspec_create),指定算法名为"SM2", 密钥参数类型为CRYPTO_ASYM_KEY_KEY_PAIR_SPEC,创建密钥参数对象(keySpec)。
369
3702. 调用[OH_CryptoAsymKeySpec_GenEcCommonParamsSpec](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-key-h.md#oh_cryptoasymkeyspec_geneccommonparamsspec),指定曲线为"NID_sm2", 生成SM2公共参数对象(sm2CommonSpec)。
371
3723. 调用[OH_CryptoAsymKeySpec_SetCommonParamsSpec](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-key-h.md#oh_cryptoasymkeyspec_setcommonparamsspec),将生成SM2公共参数对象(sm2CommonSpec)设置到密钥参数对象(keySpec)。
373
3744. 指定uint8_t类型的SM2密钥对数据(pkx、pky、sk),分别封装成[Crypto_DataBlob](../../reference/apis-crypto-architecture-kit/capi-cryptocommonapi-crypto-datablob.md)。
375
3765. 调用[OH_CryptoAsymKeySpec_SetParam](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-key-h.md#oh_cryptoasymkeyspec_setparam),指定参数类型分别为CRYPTO_ECC_PK_X_DATABLOB(pkx)、CRYPTO_ECC_PK_Y_DATABLOB(pky)、CRYPTO_ECC_SK_DATABLOB(sk), 依次传入封装后的[Crypto_DataBlob](../../reference/apis-crypto-architecture-kit/capi-cryptocommonapi-crypto-datablob.md),设置到参数对象(keySpec)。
377
378   > **注意:**
379   > pkx、pky、sk均要以大端模式输入,且必须为正数。
380
3816. 调用[OH_CryptoAsymKeyGeneratorWithSpec_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-key-h.md#oh_cryptoasymkeygeneratorwithspec_create),将参数对象(keySpec)传入,创建非对称密钥生成器(generatorSpec)。
382
3837. 调用[OH_CryptoAsymKeyGeneratorWithSpec_GenKeyPair](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-key-h.md#oh_cryptoasymkeygeneratorwithspec_genkeypair),生成SM2密钥对(keyPair)。
384
3858. 分别传入密钥对中的私钥和公钥,调用[OH_CryptoPrivKey_GetParam](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-key-h.md#oh_cryptoprivkey_getparam)和[OH_CryptoPubKey_GetParam](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-key-h.md#oh_cryptopubkey_getparam),获取SM2算法中私钥和公钥的各种密钥参数。
386
387```C++
388#include "CryptoArchitectureKit/crypto_architecture_kit.h"
389#include <string>
390
391static OH_Crypto_ErrCode GetEccKeyParams(OH_CryptoKeyPair *keyCtx, Crypto_DataBlob *pubKeyXData,
392                                         Crypto_DataBlob *pubKeyYData, Crypto_DataBlob *privKeyData)
393{
394    OH_CryptoPubKey *pubKey = OH_CryptoKeyPair_GetPubKey(keyCtx);
395    if (pubKey == nullptr) {
396        return CRYPTO_OPERTION_ERROR;
397    }
398    OH_Crypto_ErrCode ret = OH_CryptoPubKey_GetParam(pubKey, CRYPTO_ECC_PK_X_DATABLOB, pubKeyXData);
399    if (ret != CRYPTO_SUCCESS) {
400        return ret;
401    }
402    ret = OH_CryptoPubKey_GetParam(pubKey, CRYPTO_ECC_PK_Y_DATABLOB, pubKeyYData);
403    if (ret != CRYPTO_SUCCESS) {
404        return ret;
405    }
406
407    OH_CryptoPrivKey *privKey = OH_CryptoKeyPair_GetPrivKey(keyCtx);
408    if (privKey == nullptr) {
409        return CRYPTO_OPERTION_ERROR;
410    }
411    ret = OH_CryptoPrivKey_GetParam(privKey, CRYPTO_ECC_SK_DATABLOB, privKeyData);
412    return ret;
413}
414
415static void FreeEccKeyParams(Crypto_DataBlob *pubKeyXData, Crypto_DataBlob *pubKeyYData, Crypto_DataBlob *privKeyData)
416{
417    OH_Crypto_FreeDataBlob(pubKeyXData);
418    OH_Crypto_FreeDataBlob(pubKeyYData);
419    OH_Crypto_FreeDataBlob(privKeyData);
420}
421
422size_t ConvertHex(uint8_t* dest, size_t count, const char* src)
423{
424    size_t i;
425    int value;
426
427    for (i = 0; i < count && sscanf(src + i * 2, "%2x", &value) == 1; i++) {
428        dest[i] = value;
429    }
430    return i;
431}
432
433static OH_Crypto_ErrCode doTestSm2GenKeyPairBySpec()
434{
435    std::string pkXStr = "67F3B850BDC0BA5D3A29D8A0883C4B17612AB84F87F18E28F77D824A115C02C4";
436    std::string pkYStr = "D48966CE754BBBEDD6501A1385E1B205C186E926ADED44287145E8897D4B2071";
437    std::string skStr = "6330B599ECD23ABDC74B9A5B7B5E00E553005F72743101C5FAB83AEB579B7074";
438    uint8_t pkX[256] = {};
439    uint8_t pkY[256] = {};
440    uint8_t sk[256] = {};
441    size_t pkXLen = ConvertHex(pkX, pkXStr.size() / 2, pkXStr.c_str());
442    size_t pkYLen = ConvertHex(pkY, pkYStr.size() / 2, pkYStr.c_str());
443    size_t skLen = ConvertHex(sk, skStr.size() / 2, skStr.c_str());
444    Crypto_DataBlob pkXData = {.data = pkX, .len = pkXLen};
445    Crypto_DataBlob pkYData = {.data = pkY, .len = pkYLen};
446    Crypto_DataBlob skData = {.data = sk, .len = skLen};
447
448    OH_CryptoAsymKeySpec *keySpec = nullptr;
449    OH_Crypto_ErrCode ret = OH_CryptoAsymKeySpec_Create("SM2", CRYPTO_ASYM_KEY_KEY_PAIR_SPEC, &keySpec);
450    if (ret != CRYPTO_SUCCESS) {
451        return ret;
452    }
453    OH_CryptoAsymKeySpec *sm2CommonSpec = nullptr;
454    ret = OH_CryptoAsymKeySpec_GenEcCommonParamsSpec("NID_sm2", &sm2CommonSpec);
455    if (ret != CRYPTO_SUCCESS) {
456        OH_CryptoAsymKeySpec_Destroy(keySpec);
457        return ret;
458    }
459    ret = OH_CryptoAsymKeySpec_SetCommonParamsSpec(keySpec, sm2CommonSpec);
460    if (ret != CRYPTO_SUCCESS) {
461        OH_CryptoAsymKeySpec_Destroy(sm2CommonSpec);
462        OH_CryptoAsymKeySpec_Destroy(keySpec);
463        return ret;
464    }
465    ret = OH_CryptoAsymKeySpec_SetParam(keySpec, CRYPTO_ECC_PK_X_DATABLOB, &pkXData);
466    if (ret != CRYPTO_SUCCESS) {
467        OH_CryptoAsymKeySpec_Destroy(sm2CommonSpec);
468        OH_CryptoAsymKeySpec_Destroy(keySpec);
469        return ret;
470    }
471    ret = OH_CryptoAsymKeySpec_SetParam(keySpec, CRYPTO_ECC_PK_Y_DATABLOB, &pkYData);
472    if (ret != CRYPTO_SUCCESS) {
473        OH_CryptoAsymKeySpec_Destroy(sm2CommonSpec);
474        OH_CryptoAsymKeySpec_Destroy(keySpec);
475        return ret;
476    }
477    ret = OH_CryptoAsymKeySpec_SetParam(keySpec, CRYPTO_ECC_SK_DATABLOB, &skData);
478    if (ret != CRYPTO_SUCCESS) {
479        OH_CryptoAsymKeySpec_Destroy(sm2CommonSpec);
480        OH_CryptoAsymKeySpec_Destroy(keySpec);
481        return ret;
482    }
483
484    OH_CryptoAsymKeyGeneratorWithSpec *generatorSpec = nullptr;
485    ret = OH_CryptoAsymKeyGeneratorWithSpec_Create(keySpec, &generatorSpec);
486    if (ret != CRYPTO_SUCCESS) {
487        OH_CryptoAsymKeySpec_Destroy(sm2CommonSpec);
488        OH_CryptoAsymKeySpec_Destroy(keySpec);
489        return ret;
490    }
491    OH_CryptoKeyPair *keyPair = nullptr;
492    ret = OH_CryptoAsymKeyGeneratorWithSpec_GenKeyPair(generatorSpec, &keyPair);
493    if (ret != CRYPTO_SUCCESS) {
494        OH_CryptoAsymKeyGeneratorWithSpec_Destroy(generatorSpec);
495        OH_CryptoAsymKeySpec_Destroy(sm2CommonSpec);
496        OH_CryptoAsymKeySpec_Destroy(keySpec);
497        return ret;
498    }
499
500    Crypto_DataBlob dataPkX = {.data = nullptr, .len = 0};
501    Crypto_DataBlob dataPkY = {.data = nullptr, .len = 0};
502    Crypto_DataBlob dataSk = {.data = nullptr, .len = 0};
503    ret = GetEccKeyParams(keyPair, &dataPkX, &dataPkY, &dataSk);
504    if (ret != CRYPTO_SUCCESS) {
505        FreeEccKeyParams(&dataPkX, &dataPkY, &dataSk);
506        OH_CryptoKeyPair_Destroy(keyPair);
507        OH_CryptoAsymKeyGeneratorWithSpec_Destroy(generatorSpec);
508        OH_CryptoAsymKeySpec_Destroy(sm2CommonSpec);
509        OH_CryptoAsymKeySpec_Destroy(keySpec);
510        return ret;
511    }
512    FreeEccKeyParams(&dataPkX, &dataPkY, &dataSk);
513    OH_CryptoKeyPair_Destroy(keyPair);
514    OH_CryptoAsymKeyGeneratorWithSpec_Destroy(generatorSpec);
515    OH_CryptoAsymKeySpec_Destroy(sm2CommonSpec);
516    OH_CryptoAsymKeySpec_Destroy(keySpec);
517    return ret;
518}
519```