1# Generating an Asymmetric Key Pair Based on Key Parameters 2 3This 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. 4 5The **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. 6 7 8## Generating an RSA Public Key Based on Key Parameters 9 10For details about the algorithm specifications, see [RSA](crypto-asym-key-generation-conversion-spec.md#rsa). 11 121. Create an [RSACommonParamsSpec](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#rsacommonparamsspec10) object to specify the common parameter (**n**) of both the public and private keys of the RSA algorithm. 13 14 **RSACommonParamsSpec** is a child class of **AsyKeySpec**. Specify the RSA algorithm in the **algName** parameter, and set the key parameter type to **AsyKeySpecType.COMMON_PARAMS_SPEC**, which indicates the common parameter for both the public and private keys. 15 16 When key parameters are specified for generating a key, the bigint value must be a positive number in big-endian format. 17 182. Create an [RSAPubKeySpec](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#rsapubkeyspec10) object to specify the parameters (**n**, **pk**) contained in the public key of the RSA algorithm. 19 20 **RSAPubKeySpec** is a child class of **AsyKeySpec**. Specify the RSA algorithm in the **algName** parameter, and set the key parameter type to **AsyKeySpecType.PUBLIC_KEY_SPEC**, which indicates the parameters of the public key. 21 223. Use [cryptoFramework.createAsyKeyGeneratorBySpec](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#cryptoframeworkcreateasykeygeneratorbyspec10) with the **RSAPubKeySpec** object to create an asymmetric key generator (**AsyKeyGeneratorBySpec**) object. 23 244. Use [AsyKeyGeneratorBySpec.generatePubKey](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#generatepubkey-1) to generate the public key (**PubKey**). 25 265. Use [PubKey.getAsyKeySpec](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#getasykeyspec10) to obtain the modulus **n** and the public key exponent **pk** (expressed as e in the formula). 27 28- Example: Generate an RSA public key based on key parameters (using callback-based APIs). 29 ```ts 30 import { cryptoFramework } from '@kit.CryptoArchitectureKit'; 31 // Generate an RSA public key parameter (RsaPubKeySpec). 32 function genRsaPubKeySpec(nIn: bigint, eIn: bigint): cryptoFramework.RSAPubKeySpec { 33 let rsaCommSpec: cryptoFramework.RSACommonParamsSpec = { 34 n: nIn, 35 algName: 'RSA', 36 specType: cryptoFramework.AsyKeySpecType.COMMON_PARAMS_SPEC 37 }; 38 let rsaPubKeySpec: cryptoFramework.RSAPubKeySpec = { 39 params: rsaCommSpec, 40 pk: eIn, 41 algName: 'RSA', 42 specType: cryptoFramework.AsyKeySpecType.PUBLIC_KEY_SPEC 43 }; 44 return rsaPubKeySpec; 45 } 46 // Construct an RSA public key specification object based on the key parameter. 47 function genRsa2048PubKeySpec() { 48 let nIn = BigInt('0x9260d0750ae117eee55c3f3deaba74917521a262ee76007cdf8a56755ad73a1598a1408410a01434c3f5bc54a88b57fa19fc4328daea0750a4c44e88cff3b2382621b80f670464433e4336e6d003e8cd65bff211da144b88291c2259a00a72b711c116ef7686e8fee34e4d933c868187bdc26f7be071493c86f7a5941c3510806ad67b0f94d88f5cf5c02a092821d8626e8932b65c5bd8c92049c210932b7afa7ac59c0e886ae5c1edb00d8ce2c57633db26bd6639bff73cee82be9275c402b4cf2a4388da8cf8c64eefe1c5a0f5ab8057c39fa5c0589c3e253f0960332300f94bea44877b588e1edbde97cf2360727a09b775262d7ee552b3319b9266f05a25'); 49 let eIn = BigInt('0x010001'); 50 return genRsaPubKeySpec(nIn, eIn); 51 } 52 // Compare the RSA public key specifications with the expected value. 53 function compareRsaPubKeyBySpec(rsaKeySpec: cryptoFramework.RSAPubKeySpec, n: bigint | string | number, e: bigint | string | number) { 54 if (typeof n === 'string' || typeof e === 'string') { 55 console.error('type is string'); 56 return false; 57 } 58 if (typeof n === 'number' || typeof e === 'number') { 59 console.error('type is number'); 60 return false; 61 } 62 if (rsaKeySpec.params.n != n) { 63 return false; 64 } 65 if (rsaKeySpec.pk != e) { 66 return false; 67 } 68 return true; 69 } 70 // Generate an RSA public key based on the RSA public key specifications, obtain the key specifications, and compare it with the expected value. 71 function rsaUsePubKeySpecGetCallback() { 72 let rsaPubKeySpec = genRsa2048PubKeySpec(); 73 let rsaGeneratorSpec = cryptoFramework.createAsyKeyGeneratorBySpec(rsaPubKeySpec); 74 rsaGeneratorSpec.generatePubKey((error, key) => { 75 if (error) { 76 console.error('generate pubKey error' + 'error code: ' + error.code + 'error message' + error.message); 77 } 78 let pubKey = key; 79 let nBN = pubKey.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.RSA_N_BN); 80 let eBN = pubKey.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.RSA_PK_BN); 81 if (compareRsaPubKeyBySpec(rsaPubKeySpec, nBN, eBN) != true) { 82 console.error('error pub key big number'); 83 } else { 84 console.info('n, e in the pubKey are same as the spec.'); 85 } 86 }); 87 } 88 ``` 89 90- Synchronously return the result ([generatePubKeySync](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#generatepubkeysync12)): 91 ```ts 92 import { cryptoFramework } from '@kit.CryptoArchitectureKit'; 93 // Generate an RSA public key parameter (RsaPubKeySpec). 94 function genRsaPubKeySpec(nIn: bigint, eIn: bigint): cryptoFramework.RSAPubKeySpec { 95 let rsaCommSpec: cryptoFramework.RSACommonParamsSpec = { 96 n: nIn, 97 algName: 'RSA', 98 specType: cryptoFramework.AsyKeySpecType.COMMON_PARAMS_SPEC 99 }; 100 let rsaPubKeySpec: cryptoFramework.RSAPubKeySpec = { 101 params: rsaCommSpec, 102 pk: eIn, 103 algName: 'RSA', 104 specType: cryptoFramework.AsyKeySpecType.PUBLIC_KEY_SPEC 105 }; 106 return rsaPubKeySpec; 107 } 108 // Construct an RSA public key specification object based on the key parameter. 109 function genRsa2048PubKeySpec() { 110 let nIn = BigInt('0x9260d0750ae117eee55c3f3deaba74917521a262ee76007cdf8a56755ad73a1598a1408410a01434c3f5bc54a88b57fa19fc4328daea0750a4c44e88cff3b2382621b80f670464433e4336e6d003e8cd65bff211da144b88291c2259a00a72b711c116ef7686e8fee34e4d933c868187bdc26f7be071493c86f7a5941c3510806ad67b0f94d88f5cf5c02a092821d8626e8932b65c5bd8c92049c210932b7afa7ac59c0e886ae5c1edb00d8ce2c57633db26bd6639bff73cee82be9275c402b4cf2a4388da8cf8c64eefe1c5a0f5ab8057c39fa5c0589c3e253f0960332300f94bea44877b588e1edbde97cf2360727a09b775262d7ee552b3319b9266f05a25'); 111 let eIn = BigInt('0x010001'); 112 return genRsaPubKeySpec(nIn, eIn); 113 } 114 // Compare the RSA public key specifications with the expected value. 115 function compareRsaPubKeyBySpec(rsaKeySpec: cryptoFramework.RSAPubKeySpec, n: bigint | string | number, e: bigint | string | number) { 116 if (typeof n === 'string' || typeof e === 'string') { 117 console.error('type is string'); 118 return false; 119 } 120 if (typeof n === 'number' || typeof e === 'number') { 121 console.error('type is number'); 122 return false; 123 } 124 if (rsaKeySpec.params.n != n) { 125 return false; 126 } 127 if (rsaKeySpec.pk != e) { 128 return false; 129 } 130 return true; 131 } 132 // Generate an RSA public key based on the RSA public key specifications, obtain the key specifications, and compare it with the expected value. 133 function rsaUsePubKeySpecGetSync() { 134 let rsaPubKeySpec = genRsa2048PubKeySpec(); 135 let rsaGeneratorSpec = cryptoFramework.createAsyKeyGeneratorBySpec(rsaPubKeySpec); 136 try { 137 let pubKey = rsaGeneratorSpec.generatePubKeySync(); 138 if (pubKey != null) { 139 let nBN = pubKey.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.RSA_N_BN); 140 let eBN = pubKey.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.RSA_PK_BN); 141 if (compareRsaPubKeyBySpec(rsaPubKeySpec, nBN, eBN) != true) { 142 console.error('error pub key big number'); 143 } else { 144 console.info('n, e in the pubKey are same as the spec.'); 145 } 146 } else { 147 console.error('get pub key result fail!'); 148 } 149 } catch (e) { 150 console.error(`get pub key result fail, ${e.code}, ${e.message}`); 151 } 152 } 153 ``` 154 155 156## Generating an ECC Key Pair Based on Key Parameters 157 158For details about the algorithm specifications, see [ECC](crypto-asym-key-generation-conversion-spec.md#ecc). 159 1601. Create an [ECCCommonParamsSpec](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#ecccommonparamsspec10) object to specify the common parameters of both the public and private keys of the ECC algorithm. 161 **ECCCommonParamsSpec** is a child class of **AsyKeySpec**. Specify the ECC algorithm in the **algName** parameter, and set the key parameter type to **AsyKeySpecType.COMMON_PARAMS_SPEC**, which indicates the common parameter for both the public and private keys. 162 163 When key parameters are specified for generating a key, the bigint value must be a positive number in big-endian format. 164 1652. Use [cryptoFramework.createAsyKeyGeneratorBySpec](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#cryptoframeworkcreateasykeygeneratorbyspec10) with the **ECCCommonParamsSpec** object to create an asymmetric key generator (**AsyKeyGeneratorBySpec**) object. 166 1673. Use [AsyKeyGeneratorBySpec.generateKeyPair](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#generatekeypair-3) to generate a key pair (**KeyPair**). 168 1694. Use [PriKey.getAsyKeySpec](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#getasykeyspec10-1) to obtain the private key specifications, and use [PubKey.getAsyKeySpec](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#getasykeyspec10) to obtain the public key specifications of the ECC. 170 171- Example: Generate an ECC key pair based on key parameters (using promise-based APIs). 172 ```ts 173 import { cryptoFramework } from '@kit.CryptoArchitectureKit'; 174 import { BusinessError } from '@kit.BasicServicesKit'; 175 176 // Print bigint information. 177 function showBigIntInfo(bnName: string, bnValue: bigint | string | number) { 178 if (typeof bnValue === 'string') { 179 console.error('type is string'); 180 return; 181 } 182 if (typeof bnValue === 'number') { 183 console.error('type is number'); 184 return; 185 } 186 console.info(bnName + ':'); 187 console.info('. Decimal: ' + bnValue.toString()); 188 console.info('. Hexadecimal: ' + bnValue.toString(16)); 189 console.info('. Length (bits): ' + bnValue.toString(2).length); 190 } 191 // Construct the EccCommonSpec struct, which defines the common parameters of the ECC public and private keys. 192 function genEccCommonSpec(): cryptoFramework.ECCCommonParamsSpec { 193 let fieldFp: cryptoFramework.ECFieldFp = { 194 fieldType: 'Fp', 195 p: BigInt('0xffffffffffffffffffffffffffffffff000000000000000000000001') 196 } 197 let G: cryptoFramework.Point = { 198 x: BigInt('0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21'), 199 y: BigInt('0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34') 200 } 201 let eccCommonSpec: cryptoFramework.ECCCommonParamsSpec = { 202 algName: 'ECC', 203 specType: cryptoFramework.AsyKeySpecType.COMMON_PARAMS_SPEC, 204 field: fieldFp, 205 a: BigInt('0xfffffffffffffffffffffffffffffffefffffffffffffffffffffffe'), 206 b: BigInt('0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4'), 207 g: G, 208 n: BigInt('0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d'), 209 h: 1 210 } 211 return eccCommonSpec; 212 } 213 // Print the ECC key specifications. 214 function showEccSpecDetailInfo(key: cryptoFramework.PubKey | cryptoFramework.PriKey, keyType: string) { 215 console.info('show detail of ' + keyType + ':'); 216 try { 217 let p = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_FP_P_BN); 218 showBigIntInfo('--- p', p); // length is 224, hex : ffffffffffffffffffffffffffffffff000000000000000000000001 219 let a = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_A_BN); 220 showBigIntInfo('--- a', a); // length is 224, hex : fffffffffffffffffffffffffffffffefffffffffffffffffffffffe 221 let b = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_B_BN); 222 showBigIntInfo('--- b', b); // length is 224, hex : b4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4 223 let gX = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_G_X_BN); 224 showBigIntInfo('--- gX', gX); // length is 224, hex : b70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21 225 let gY = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_G_Y_BN); 226 showBigIntInfo('--- gY', gY); // length is 224, hex : bd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34 227 let n = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_N_BN); 228 showBigIntInfo('--- n', n); // length is 224, hex : ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d 229 let h = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_H_NUM); 230 console.warn('--- h: ' + h); // key h: 1 231 let fieldType = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_FIELD_TYPE_STR); 232 console.warn('--- field type: ' + fieldType); // key field type: Fp 233 let fieldSize = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_FIELD_SIZE_NUM); 234 console.warn('--- field size: ' + fieldSize); // key field size: 224 235 let curveName = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_CURVE_NAME_STR); 236 console.warn('--- curve name: ' + curveName); // key curve name: NID_secp224r1 237 if (keyType == 'priKey') { 238 let sk = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_SK_BN); 239 showBigIntInfo('--- sk', sk); 240 } else if (keyType == 'pubKey') { 241 let pkX = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_PK_X_BN); 242 showBigIntInfo('--- pkX', pkX); 243 let pkY = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_PK_Y_BN); 244 showBigIntInfo('--- pkY', pkY); 245 } 246 } catch (error) { 247 console.error('getAsyKeySpec error'); 248 let e: BusinessError = error as BusinessError; 249 console.error(`getAsyKeySpec failed, ${e.code}, ${e.message}`); 250 } 251 } 252 // Generate an ECC key pair based on the EccCommonSpec instance and obtain the key specifications. 253 function testEccUseCommKeySpecGet() { 254 try { 255 let commKeySpec = genEccCommonSpec(); // Construct the EccCommonSpec object. 256 let generatorBySpec = cryptoFramework.createAsyKeyGeneratorBySpec(commKeySpec); // Create an AsyKeyGenerator instance based on the EccCommonSpec object. 257 let keyPairPromise = generatorBySpec.generateKeyPair(); // Generate an ECC key pair. 258 keyPairPromise.then(keyPair => {// Use AsyKeyGenerator to create an ECC key pair. 259 showEccSpecDetailInfo(keyPair.priKey, "priKey"); // Obtain the ECC private key specifications. 260 showEccSpecDetailInfo(keyPair.pubKey, "pubKey"); // Obtain the ECC public key specifications. 261 }).catch((error: BusinessError) => { 262 // Capture exceptions such as logic errors asynchronously. 263 console.error('generateComm error'); 264 console.error('error code: ' + error.code + ', message is: ' + error.message); 265 }) 266 } catch (error) { 267 // Capture parameter errors synchronously. 268 console.error('testEccUseCommSpec error'); 269 let e: BusinessError = error as BusinessError; 270 console.error(`ecc comm spec failed, ${e.code}, ${e.message}`); 271 } 272 } 273 ``` 274 275- Synchronously return the result ([generateKeyPairSync](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#generatekeypairsync12)): 276 ```ts 277 import { cryptoFramework } from '@kit.CryptoArchitectureKit'; 278 279 function showBigIntInfo(bnName: string, bnValue: bigint | string | number) { 280 if (typeof bnValue === 'string') { 281 console.error('type is string'); 282 return; 283 } 284 if (typeof bnValue === 'number') { 285 console.error('type is number'); 286 return; 287 } 288 console.info(bnName + ':'); 289 console.info('. Decimal: ' + bnValue.toString()); 290 console.info('. Hexadecimal: ' + bnValue.toString(16)); 291 console.info('. Length (bits): ' + bnValue.toString(2).length); 292 } 293 // Construct the EccCommonSpec struct, which defines the common parameters of the ECC public and private keys. 294 function genEccCommonSpec(): cryptoFramework.ECCCommonParamsSpec { 295 let fieldFp: cryptoFramework.ECFieldFp = { 296 fieldType: 'Fp', 297 p: BigInt('0xffffffffffffffffffffffffffffffff000000000000000000000001') 298 } 299 let G: cryptoFramework.Point = { 300 x: BigInt('0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21'), 301 y: BigInt('0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34') 302 } 303 let eccCommonSpec: cryptoFramework.ECCCommonParamsSpec = { 304 algName: 'ECC', 305 specType: cryptoFramework.AsyKeySpecType.COMMON_PARAMS_SPEC, 306 field: fieldFp, 307 a: BigInt('0xfffffffffffffffffffffffffffffffefffffffffffffffffffffffe'), 308 b: BigInt('0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4'), 309 g: G, 310 n: BigInt('0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d'), 311 h: 1 312 } 313 return eccCommonSpec; 314 } 315 // Print the ECC key specifications. 316 function showEccSpecDetailInfo(key: cryptoFramework.PubKey | cryptoFramework.PriKey, keyType: string) { 317 console.info('show detail of ' + keyType + ':'); 318 try { 319 let p = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_FP_P_BN); 320 showBigIntInfo('--- p', p); // length is 224, hex : ffffffffffffffffffffffffffffffff000000000000000000000001 321 let a = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_A_BN); 322 showBigIntInfo('--- a', a); // length is 224, hex : fffffffffffffffffffffffffffffffefffffffffffffffffffffffe 323 let b = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_B_BN); 324 showBigIntInfo('--- b', b); // length is 224, hex : b4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4 325 let gX = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_G_X_BN); 326 showBigIntInfo('--- gX', gX); // length is 224, hex : b70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21 327 let gY = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_G_Y_BN); 328 showBigIntInfo('--- gY', gY); // length is 224, hex : bd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34 329 let n = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_N_BN); 330 showBigIntInfo('--- n', n); // length is 224, hex : ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d 331 let h = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_H_NUM); 332 console.warn('--- h: ' + h); // key h: 1 333 let fieldType = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_FIELD_TYPE_STR); 334 console.warn('--- field type: ' + fieldType); // key field type: Fp 335 let fieldSize = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_FIELD_SIZE_NUM); 336 console.warn('--- field size: ' + fieldSize); // key field size: 224 337 let curveName = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_CURVE_NAME_STR); 338 console.warn('--- curve name: ' + curveName); // key curve name: NID_secp224r1 339 if (keyType == 'priKey') { 340 let sk = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_SK_BN); 341 showBigIntInfo('--- sk', sk); 342 } else if (keyType == 'pubKey') { 343 let pkX = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_PK_X_BN); 344 showBigIntInfo('--- pkX', pkX); 345 let pkY = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_PK_Y_BN); 346 showBigIntInfo('--- pkY', pkY); 347 } 348 } catch (e) { 349 console.error(`getAsyKeySpec failed, ${e.code}, ${e.message}`); 350 } 351 } 352 // Generate an ECC key pair based on the EccCommonSpec instance and obtain the key specifications. 353 function testEccUseCommKeySpecGetSync() { 354 try { 355 let commKeySpec = genEccCommonSpec(); // Construct the EccCommonSpec object. 356 let generatorBySpec = cryptoFramework.createAsyKeyGeneratorBySpec(commKeySpec); // Create an AsyKeyGenerator instance based on the EccCommonSpec object. 357 let keyPair = generatorBySpec.generateKeyPairSync(); // Generate an ECC key pair. 358 if (keyPair != null) { 359 showEccSpecDetailInfo(keyPair.priKey, "priKey"); // Obtain the ECC private key specifications. 360 showEccSpecDetailInfo(keyPair.pubKey, "pubKey"); // Obtain the ECC public key specifications. 361 } else { 362 console.error('get key pair result fail!'); 363 } 364 } catch (e) { 365 // Capture exceptions such as logic errors here. 366 console.error(`get key pair result fail, ${e.code}, ${e.message}`); 367 } 368 } 369 ``` 370 371 372## Generating an SM2 Key Pair Based on the Elliptic Curve Name 373 374For details about the algorithm specifications, see [SM2](crypto-asym-key-generation-conversion-spec.md#sm2). 375 3761. Create an [ECCCommonParamsSpec](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#ecccommonparamsspec10) object to specify common parameters of the private and public keys. Use [genECCCommonParamsSpec](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#genecccommonparamsspec11) with an NID string to generate the common parameters for the SM2 key pair. 377 378 When key parameters are specified for generating a key, the bigint value must be a positive number in big-endian format. 379 3802. Create an [ECCKeyPairSpec](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#ecckeypairspec10) object with **algName** set to **SM2** to specify the SM2 key pair parameters. 381 3823. Use [cryptoFramework.createAsyKeyGeneratorBySpec](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#cryptoframeworkcreateasykeygeneratorbyspec10) with the **ECCKeyPairSpec** object to create an asymmetric key generator object. 383 3844. Use [AsyKeyGeneratorBySpec.generateKeyPair](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#generatekeypair-3) to generate an SM2 key pair (**KeyPair**). 385 3865. Use [PriKey.getAsyKeySpec](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#getasykeyspec10-1) to obtain elliptic curve parameters of SM2. 387 388- Example: Generate an SM2 key based on the elliptic curve name (using promise-based APIs) 389 ```ts 390 import { cryptoFramework } from '@kit.CryptoArchitectureKit'; 391 392 function genSM2KeyPairSpec() { 393 let sm2CommonParamsSpec = cryptoFramework.ECCKeyUtil.genECCCommonParamsSpec('NID_sm2'); 394 let sm2KeyPairSpec: cryptoFramework.ECCKeyPairSpec = { 395 algName: "SM2", 396 specType: cryptoFramework.AsyKeySpecType.KEY_PAIR_SPEC, 397 params: sm2CommonParamsSpec, 398 sk: BigInt('0x6330B599ECD23ABDC74B9A5B7B5E00E553005F72743101C5FAB83AEB579B7074'), 399 pk: { 400 x: BigInt('0x67F3B850BDC0BA5D3A29D8A0883C4B17612AB84F87F18E28F77D824A115C02C4'), 401 y: BigInt('0xD48966CE754BBBEDD6501A1385E1B205C186E926ADED44287145E8897D4B2071') 402 }, 403 }; 404 return sm2KeyPairSpec; 405 } 406 407 async function sm2Test() { 408 let sm2KeyPairSpec = genSM2KeyPairSpec(); 409 let generatorBySpec = cryptoFramework.createAsyKeyGeneratorBySpec(sm2KeyPairSpec); 410 let keyPair = await generatorBySpec.generateKeyPair(); 411 let sm2CurveName = keyPair.priKey.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_CURVE_NAME_STR); 412 console.info('ECC_CURVE_NAME_STR: ' + sm2CurveName); // NID_sm2 413 } 414 ``` 415 416- Synchronously return the result ([generateKeyPairSync](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#generatekeypairsync12)): 417 ```ts 418 import { cryptoFramework } from '@kit.CryptoArchitectureKit'; 419 420 function genSM2KeyPairSpec() { 421 let sm2CommonParamsSpec = cryptoFramework.ECCKeyUtil.genECCCommonParamsSpec('NID_sm2'); 422 let sm2KeyPairSpec: cryptoFramework.ECCKeyPairSpec = { 423 algName: "SM2", 424 specType: cryptoFramework.AsyKeySpecType.KEY_PAIR_SPEC, 425 params: sm2CommonParamsSpec, 426 sk: BigInt('0x6330B599ECD23ABDC74B9A5B7B5E00E553005F72743101C5FAB83AEB579B7074'), 427 pk: { 428 x: BigInt('0x67F3B850BDC0BA5D3A29D8A0883C4B17612AB84F87F18E28F77D824A115C02C4'), 429 y: BigInt('0xD48966CE754BBBEDD6501A1385E1B205C186E926ADED44287145E8897D4B2071') 430 }, 431 }; 432 return sm2KeyPairSpec; 433 } 434 function sm2TestSync() { 435 let sm2KeyPairSpec = genSM2KeyPairSpec(); 436 let generatorBySpec = cryptoFramework.createAsyKeyGeneratorBySpec(sm2KeyPairSpec); 437 try { 438 let keyPair = generatorBySpec.generateKeyPairSync(); 439 if (keyPair != null) { 440 let sm2CurveName = keyPair.priKey.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_CURVE_NAME_STR); 441 console.info('ECC_CURVE_NAME_STR: ' + sm2CurveName); // NID_sm2 442 } else { 443 console.error('get key pair result fail!'); 444 } 445 } catch (e) { 446 console.error(`get key pair result fail, ${e.code}, ${e.message}`); 447 } 448 } 449 ``` 450