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```