1# 指定密钥参数生成非对称密钥对(ArkTS) 2 3以RSA、ECC、SM2为例,根据指定的密钥参数,生成非对称密钥对(KeyPair),并获取密钥参数属性。 4 5该对象可用于后续的加解密等操作。获取的密钥参数属性可用于存储或运输。 6 7## 指定密钥参数生成RSA公钥 8 9对应的算法规格请查看[非对称密钥生成和转换规格:RSA](crypto-asym-key-generation-conversion-spec.md#rsa)。 10 111. 构造[RSACommonParamsSpec](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#rsacommonparamsspec10)对象,用于指定RSA算法中公私钥包含的公共参数(n)。 12 13 RSACommonParamsSpec是AsyKeySpec的子类。需要通过参数algName指定算法'RSA';指定密钥参数类型AsyKeySpecType.COMMON_PARAMS_SPEC,表示是公私钥中包含的公共参数。 14 15 使用密钥参数生成密钥时,用到的bigint类型需要以大端模式输入,且必须为正数。 16 172. 创建[RSAPubKeySpec](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#rsapubkeyspec10)对象,用于指定RSA算法中公钥包含的参数(n, pk)。 18 19 RSAPubKeySpec是AsyKeySpec的子类。通过参数algName指定算法'RSA';指定密钥参数类型AsyKeySpecType.PUBLIC_KEY_SPEC,表示是公钥中包含的参数。 20 213. 调用[cryptoFramework.createAsyKeyGeneratorBySpec](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#cryptoframeworkcreateasykeygeneratorbyspec10),将RSAPubKeySpec对象传入,创建非对称密钥生成器(AsyKeyGeneratorBySpec)。 22 234. 调用[AsyKeyGeneratorBySpec.generatePubKey](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#generatepubkey-1),获得指定的公钥(PubKey)。 24 255. 调用[PubKey.getAsyKeySpec](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#getasykeyspec10),获取模数n和公钥pk(即公钥指数e)。 26 27- 以使用callback方式根据密钥参数生成RSA公钥为例: 28 ```ts 29 import { cryptoFramework } from '@kit.CryptoArchitectureKit'; 30 // RSA公钥密钥参数生成函数。 31 function genRsaPubKeySpec(nIn: bigint, eIn: bigint): cryptoFramework.RSAPubKeySpec { 32 let rsaCommSpec: cryptoFramework.RSACommonParamsSpec = { 33 n: nIn, 34 algName: 'RSA', 35 specType: cryptoFramework.AsyKeySpecType.COMMON_PARAMS_SPEC 36 }; 37 let rsaPubKeySpec: cryptoFramework.RSAPubKeySpec = { 38 params: rsaCommSpec, 39 pk: eIn, 40 algName: 'RSA', 41 specType: cryptoFramework.AsyKeySpecType.PUBLIC_KEY_SPEC 42 }; 43 return rsaPubKeySpec; 44 } 45 // 根据密钥参数构造RSA公钥规范对象。 46 function genRsa2048PubKeySpec() { 47 let nIn = BigInt('0x9260d0750ae117eee55c3f3deaba74917521a262ee76007cdf8a56755ad73a1598a1408410a01434c3f5bc54a88b57fa19fc4328daea0750a4c44e88cff3b2382621b80f670464433e4336e6d003e8cd65bff211da144b88291c2259a00a72b711c116ef7686e8fee34e4d933c868187bdc26f7be071493c86f7a5941c3510806ad67b0f94d88f5cf5c02a092821d8626e8932b65c5bd8c92049c210932b7afa7ac59c0e886ae5c1edb00d8ce2c57633db26bd6639bff73cee82be9275c402b4cf2a4388da8cf8c64eefe1c5a0f5ab8057c39fa5c0589c3e253f0960332300f94bea44877b588e1edbde97cf2360727a09b775262d7ee552b3319b9266f05a25'); 48 let eIn = BigInt('0x010001'); 49 return genRsaPubKeySpec(nIn, eIn); 50 } 51 // 将RSA公钥规格与预期值进行比较。 52 function compareRsaPubKeyBySpec(rsaKeySpec: cryptoFramework.RSAPubKeySpec, n: bigint | string | number, e: bigint | string | number) { 53 if (typeof n === 'string' || typeof e === 'string') { 54 console.error('type is string'); 55 return false; 56 } 57 if (typeof n === 'number' || typeof e === 'number') { 58 console.error('type is number'); 59 return false; 60 } 61 if (rsaKeySpec.params.n !== n) { 62 return false; 63 } 64 if (rsaKeySpec.pk !== e) { 65 return false; 66 } 67 return true; 68 } 69 // 根据RSA公钥规格生成RSA公钥,获取密钥规格,并与预期值进行比较。 70 function rsaUsePubKeySpecGetCallback() { 71 let rsaPubKeySpec = genRsa2048PubKeySpec(); 72 let rsaGeneratorSpec = cryptoFramework.createAsyKeyGeneratorBySpec(rsaPubKeySpec); 73 rsaGeneratorSpec.generatePubKey((error, key) => { 74 if (error) { 75 console.error('generate pubKey error' + 'error code: ' + error.code + 'error message' + error.message); 76 } 77 let pubKey = key; 78 let nBN = pubKey.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.RSA_N_BN); 79 let eBN = pubKey.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.RSA_PK_BN); 80 if (compareRsaPubKeyBySpec(rsaPubKeySpec, nBN, eBN) !== true) { 81 console.error('error pub key big number'); 82 } else { 83 console.info('n, e in the pubKey are same as the spec.'); 84 } 85 }); 86 } 87 ``` 88 89- 同步返回结果(调用方法[generatePubKeySync](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#generatepubkeysync12)): 90 ```ts 91 import { cryptoFramework } from '@kit.CryptoArchitectureKit'; 92 // RSA公钥密钥参数生成函数。 93 function genRsaPubKeySpec(nIn: bigint, eIn: bigint): cryptoFramework.RSAPubKeySpec { 94 let rsaCommSpec: cryptoFramework.RSACommonParamsSpec = { 95 n: nIn, 96 algName: 'RSA', 97 specType: cryptoFramework.AsyKeySpecType.COMMON_PARAMS_SPEC 98 }; 99 let rsaPubKeySpec: cryptoFramework.RSAPubKeySpec = { 100 params: rsaCommSpec, 101 pk: eIn, 102 algName: 'RSA', 103 specType: cryptoFramework.AsyKeySpecType.PUBLIC_KEY_SPEC 104 }; 105 return rsaPubKeySpec; 106 } 107 // 根据密钥参数构造RSA公钥规范对象。 108 function genRsa2048PubKeySpec() { 109 let nIn = BigInt('0x9260d0750ae117eee55c3f3deaba74917521a262ee76007cdf8a56755ad73a1598a1408410a01434c3f5bc54a88b57fa19fc4328daea0750a4c44e88cff3b2382621b80f670464433e4336e6d003e8cd65bff211da144b88291c2259a00a72b711c116ef7686e8fee34e4d933c868187bdc26f7be071493c86f7a5941c3510806ad67b0f94d88f5cf5c02a092821d8626e8932b65c5bd8c92049c210932b7afa7ac59c0e886ae5c1edb00d8ce2c57633db26bd6639bff73cee82be9275c402b4cf2a4388da8cf8c64eefe1c5a0f5ab8057c39fa5c0589c3e253f0960332300f94bea44877b588e1edbde97cf2360727a09b775262d7ee552b3319b9266f05a25'); 110 let eIn = BigInt('0x010001'); 111 return genRsaPubKeySpec(nIn, eIn); 112 } 113 // 将RSA公钥规格与预期值进行比较。 114 function compareRsaPubKeyBySpec(rsaKeySpec: cryptoFramework.RSAPubKeySpec, n: bigint | string | number, e: bigint | string | number) { 115 if (typeof n === 'string' || typeof e === 'string') { 116 console.error('type is string'); 117 return false; 118 } 119 if (typeof n === 'number' || typeof e === 'number') { 120 console.error('type is number'); 121 return false; 122 } 123 if (rsaKeySpec.params.n !== n) { 124 return false; 125 } 126 if (rsaKeySpec.pk !== e) { 127 return false; 128 } 129 return true; 130 } 131 // 根据RSA公钥规格生成RSA公钥,获取密钥规格,并与预期值进行比较。 132 function rsaUsePubKeySpecGetSync() { 133 let rsaPubKeySpec = genRsa2048PubKeySpec(); 134 let rsaGeneratorSpec = cryptoFramework.createAsyKeyGeneratorBySpec(rsaPubKeySpec); 135 try { 136 let pubKey = rsaGeneratorSpec.generatePubKeySync(); 137 if (pubKey !== null) { 138 let nBN = pubKey.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.RSA_N_BN); 139 let eBN = pubKey.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.RSA_PK_BN); 140 if (compareRsaPubKeyBySpec(rsaPubKeySpec, nBN, eBN) !== true) { 141 console.error('error pub key big number'); 142 } else { 143 console.info('n, e in the pubKey are same as the spec.'); 144 } 145 } else { 146 console.error('get pub key result fail!'); 147 } 148 } catch (e) { 149 console.error(`get pub key result fail, ${e.code}, ${e.message}`); 150 } 151 } 152 ``` 153 154## 指定密钥参数生成ECC密钥对 155 156对应的算法规格请查看[非对称密钥生成和转换规格:ECC](crypto-asym-key-generation-conversion-spec.md#ecc)。 157 1581. 构造[ECCCommonParamsSpec](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#ecccommonparamsspec10)对象,用于指定ECC算法中公私钥包含的公共参数。 159 ECCCommonParamsSpec是AsyKeySpec的子类。需要通过参数algName指定算法'ECC';指定密钥参数类型AsyKeySpecType.COMMON_PARAMS_SPEC,表示是公私钥中包含的公共参数。 160 161 使用密钥参数生成密钥时,用到的bigint类型需要以大端模式输入,且必须为正数。 162 1632. 调用[cryptoFramework.createAsyKeyGeneratorBySpec](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#cryptoframeworkcreateasykeygeneratorbyspec10),将ECCCommonParamsSpec对象传入,创建非对称密钥生成器(AsyKeyGeneratorBySpec)。 164 1653. 调用[AsyKeyGeneratorBySpec.generateKeyPair](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#generatekeypair-3),得到随机生成的密钥对(KeyPair)。 166 1674. 分别传入密钥对中的私钥和公钥,调用[PriKey.getAsyKeySpec](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#getasykeyspec10-1)和[PubKey.getAsyKeySpec](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#getasykeyspec10),获取ECC算法中私钥和公钥的各种密钥参数。 168 169- 以使用Promise方式根据密钥参数生成ECC密钥为例: 170 ```ts 171 import { cryptoFramework } from '@kit.CryptoArchitectureKit'; 172 import { BusinessError } from '@kit.BasicServicesKit'; 173 174 // 打印bigint信息。 175 function showBigIntInfo(bnName: string, bnValue: bigint | string | number) { 176 if (typeof bnValue === 'string') { 177 console.error('type is string'); 178 return; 179 } 180 if (typeof bnValue === 'number') { 181 console.error('type is number'); 182 return; 183 } 184 console.info(bnName + ':'); 185 console.info('. Decimal: ' + bnValue.toString()); 186 console.info('. Hexadecimal: ' + bnValue.toString(16)); 187 console.info('. Length (bits): ' + bnValue.toString(2).length); 188 } 189 // 根据关键规范构造EccCommonSpec结构体。EccCommonSpec结构体定义了ECC私钥和公钥的公共参数。 190 function genEccCommonSpec(): cryptoFramework.ECCCommonParamsSpec { 191 let fieldFp: cryptoFramework.ECFieldFp = { 192 fieldType: 'Fp', 193 p: BigInt('0xffffffffffffffffffffffffffffffff000000000000000000000001') 194 } 195 let G: cryptoFramework.Point = { 196 x: BigInt('0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21'), 197 y: BigInt('0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34') 198 } 199 let eccCommonSpec: cryptoFramework.ECCCommonParamsSpec = { 200 algName: 'ECC', 201 specType: cryptoFramework.AsyKeySpecType.COMMON_PARAMS_SPEC, 202 field: fieldFp, 203 a: BigInt('0xfffffffffffffffffffffffffffffffefffffffffffffffffffffffe'), 204 b: BigInt('0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4'), 205 g: G, 206 n: BigInt('0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d'), 207 h: 1 208 } 209 return eccCommonSpec; 210 } 211 // 打印ECC密钥规格。 212 function showEccSpecDetailInfo(key: cryptoFramework.PubKey | cryptoFramework.PriKey, keyType: string) { 213 console.info('show detail of ' + keyType + ':'); 214 try { 215 let p = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_FP_P_BN); 216 showBigIntInfo('--- p', p); // length is 224, hex : ffffffffffffffffffffffffffffffff000000000000000000000001 217 let a = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_A_BN); 218 showBigIntInfo('--- a', a); // length is 224, hex : fffffffffffffffffffffffffffffffefffffffffffffffffffffffe 219 let b = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_B_BN); 220 showBigIntInfo('--- b', b); // length is 224, hex : b4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4 221 let gX = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_G_X_BN); 222 showBigIntInfo('--- gX', gX); // length is 224, hex : b70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21 223 let gY = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_G_Y_BN); 224 showBigIntInfo('--- gY', gY); // length is 224, hex : bd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34 225 let n = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_N_BN); 226 showBigIntInfo('--- n', n); // length is 224, hex : ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d 227 let h = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_H_NUM); 228 console.warn('--- h: ' + h); // key h: 1 229 let fieldType = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_FIELD_TYPE_STR); 230 console.warn('--- field type: ' + fieldType); // key field type: Fp 231 let fieldSize = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_FIELD_SIZE_NUM); 232 console.warn('--- field size: ' + fieldSize); // key field size: 224 233 let curveName = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_CURVE_NAME_STR); 234 console.warn('--- curve name: ' + curveName); // key curve name: NID_secp224r1 235 if (keyType === 'priKey') { 236 let sk = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_SK_BN); 237 showBigIntInfo('--- sk', sk); 238 } else if (keyType === 'pubKey') { 239 let pkX = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_PK_X_BN); 240 showBigIntInfo('--- pkX', pkX); 241 let pkY = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_PK_Y_BN); 242 showBigIntInfo('--- pkY', pkY); 243 } 244 } catch (error) { 245 console.error('getAsyKeySpec error'); 246 let e: BusinessError = error as BusinessError; 247 console.error(`getAsyKeySpec failed, ${e.code}, ${e.message}`); 248 } 249 } 250 // 根据EccCommonSpec实例生成ECC密钥对,获取密钥规格。 251 function testEccUseCommKeySpecGet() { 252 try { 253 let commKeySpec = genEccCommonSpec(); // 使用参数属性,构造ECC公私钥公共密钥参数对象。 254 let generatorBySpec = cryptoFramework.createAsyKeyGeneratorBySpec(commKeySpec); // 使用密钥参数对象创建生成器。 255 let keyPairPromise = generatorBySpec.generateKeyPair(); // Generate an ECC key pair. 256 keyPairPromise.then(keyPair => { // 使用生成器创建ECC密钥对。 257 showEccSpecDetailInfo(keyPair.priKey, 'priKey'); // 对私钥获取相关密钥参数属性。 258 showEccSpecDetailInfo(keyPair.pubKey, 'pubKey'); // 对公钥获取相关密钥参数属性。 259 }).catch((error: BusinessError) => { 260 // 逻辑错误等异步异常在此捕获。 261 console.error('generateComm error'); 262 console.error('error code: ' + error.code + ', message is: ' + error.message); 263 }) 264 } catch (error) { 265 // 参数错误等同步异常在此捕获。 266 console.error('testEccUseCommSpec error'); 267 let e: BusinessError = error as BusinessError; 268 console.error(`ecc comm spec failed, ${e.code}, ${e.message}`); 269 } 270 } 271 ``` 272 273- 同步返回结果(调用方法[generateKeyPairSync](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#generatekeypairsync12)): 274 ```ts 275 import { cryptoFramework } from '@kit.CryptoArchitectureKit'; 276 277 function showBigIntInfo(bnName: string, bnValue: bigint | string | number) { 278 if (typeof bnValue === 'string') { 279 console.error('type is string'); 280 return; 281 } 282 if (typeof bnValue === 'number') { 283 console.error('type is number'); 284 return; 285 } 286 console.info(bnName + ':'); 287 console.info('. Decimal: ' + bnValue.toString()); 288 console.info('. Hexadecimal: ' + bnValue.toString(16)); 289 console.info('. Length (bits): ' + bnValue.toString(2).length); 290 } 291 // 根据关键规范构造EccCommonSpec结构体。EccCommonSpec结构体定义了ECC私钥和公钥的公共参数。 292 function genEccCommonSpec(): cryptoFramework.ECCCommonParamsSpec { 293 let fieldFp: cryptoFramework.ECFieldFp = { 294 fieldType: 'Fp', 295 p: BigInt('0xffffffffffffffffffffffffffffffff000000000000000000000001') 296 } 297 let G: cryptoFramework.Point = { 298 x: BigInt('0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21'), 299 y: BigInt('0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34') 300 } 301 let eccCommonSpec: cryptoFramework.ECCCommonParamsSpec = { 302 algName: 'ECC', 303 specType: cryptoFramework.AsyKeySpecType.COMMON_PARAMS_SPEC, 304 field: fieldFp, 305 a: BigInt('0xfffffffffffffffffffffffffffffffefffffffffffffffffffffffe'), 306 b: BigInt('0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4'), 307 g: G, 308 n: BigInt('0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d'), 309 h: 1 310 } 311 return eccCommonSpec; 312 } 313 // 打印ECC密钥规格。 314 function showEccSpecDetailInfo(key: cryptoFramework.PubKey | cryptoFramework.PriKey, keyType: string) { 315 console.info('show detail of ' + keyType + ':'); 316 try { 317 let p = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_FP_P_BN); 318 showBigIntInfo('--- p', p); // length is 224, hex : ffffffffffffffffffffffffffffffff000000000000000000000001 319 let a = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_A_BN); 320 showBigIntInfo('--- a', a); // length is 224, hex : fffffffffffffffffffffffffffffffefffffffffffffffffffffffe 321 let b = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_B_BN); 322 showBigIntInfo('--- b', b); // length is 224, hex : b4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4 323 let gX = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_G_X_BN); 324 showBigIntInfo('--- gX', gX); // length is 224, hex : b70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21 325 let gY = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_G_Y_BN); 326 showBigIntInfo('--- gY', gY); // length is 224, hex : bd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34 327 let n = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_N_BN); 328 showBigIntInfo('--- n', n); // length is 224, hex : ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d 329 let h = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_H_NUM); 330 console.warn('--- h: ' + h); // key h: 1 331 let fieldType = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_FIELD_TYPE_STR); 332 console.warn('--- field type: ' + fieldType); // key field type: Fp 333 let fieldSize = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_FIELD_SIZE_NUM); 334 console.warn('--- field size: ' + fieldSize); // key field size: 224 335 let curveName = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_CURVE_NAME_STR); 336 console.warn('--- curve name: ' + curveName); // key curve name: NID_secp224r1 337 if (keyType === 'priKey') { 338 let sk = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_SK_BN); 339 showBigIntInfo('--- sk', sk); 340 } else if (keyType === 'pubKey') { 341 let pkX = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_PK_X_BN); 342 showBigIntInfo('--- pkX', pkX); 343 let pkY = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_PK_Y_BN); 344 showBigIntInfo('--- pkY', pkY); 345 } 346 } catch (e) { 347 console.error(`getAsyKeySpec failed, ${e.code}, ${e.message}`); 348 } 349 } 350 // 根据EccCommonSpec实例生成ECC密钥对,获取密钥规格。 351 function testEccUseCommKeySpecGetSync() { 352 try { 353 let commKeySpec = genEccCommonSpec(); // 使用参数属性,构造ECC公私钥公共密钥参数对象。 354 let generatorBySpec = cryptoFramework.createAsyKeyGeneratorBySpec(commKeySpec); // 使用密钥参数对象创建生成器。 355 let keyPair = generatorBySpec.generateKeyPairSync(); // Generate an ECC key pair. 356 if (keyPair !== null) { 357 showEccSpecDetailInfo(keyPair.priKey, 'priKey'); // 对私钥获取相关密钥参数属性。 358 showEccSpecDetailInfo(keyPair.pubKey, 'pubKey'); // 对公钥获取相关密钥参数属性。 359 } else { 360 console.error('get key pair result fail!'); 361 } 362 } catch (e) { 363 // 逻辑错误等异常在此捕获。 364 console.error(`get key pair result fail, ${e.code}, ${e.message}`); 365 } 366 } 367 ``` 368 369 370## 根据椭圆曲线名生成SM2密钥对 371 372对应的算法规格请查看[非对称密钥生成和转换规格:SM2](crypto-asym-key-generation-conversion-spec.md#sm2)。 373 3741. 构造[ECCCommonParamsSpec](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#ecccommonparamsspec10)对象,用于指定非对称公共密钥参数。根据[genECCCommonParamsSpec](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#genecccommonparamsspec11)接口传入相应的NID字符串名称生成相应的非对称公共密钥参数。 375 376 使用密钥参数生成密钥时,用到的bigint类型需要以大端模式输入,且必须为正数。 377 3782. 创建[ECCKeyPairSpec](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#ecckeypairspec10)对象,并且algName设置为SM2,用于指定SM2算法中密钥对包含的参数。 379 3803. 调用[cryptoFramework.createAsyKeyGeneratorBySpec](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#cryptoframeworkcreateasykeygeneratorbyspec10),将ECCKeyPairSpec对象传入,创建非对称密钥生成器。 381 3824. 调用[AsyKeyGeneratorBySpec.generateKeyPair](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#generatekeypair-3),得到各项数据与密钥参数一致的密钥对(KeyPair)。 383 3845. 调用[PriKey.getAsyKeySpec](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#getasykeyspec10-1),获取SM2算法中椭圆曲线参数。 385 386- 以使用Promise方式根据椭圆曲线名生成SM2密钥为例: 387 ```ts 388 import { cryptoFramework } from '@kit.CryptoArchitectureKit'; 389 390 function genSM2KeyPairSpec() { 391 let sm2CommonParamsSpec = cryptoFramework.ECCKeyUtil.genECCCommonParamsSpec('NID_sm2'); 392 let sm2KeyPairSpec: cryptoFramework.ECCKeyPairSpec = { 393 algName: "SM2", 394 specType: cryptoFramework.AsyKeySpecType.KEY_PAIR_SPEC, 395 params: sm2CommonParamsSpec, 396 sk: BigInt('0x6330B599ECD23ABDC74B9A5B7B5E00E553005F72743101C5FAB83AEB579B7074'), 397 pk: { 398 x: BigInt('0x67F3B850BDC0BA5D3A29D8A0883C4B17612AB84F87F18E28F77D824A115C02C4'), 399 y: BigInt('0xD48966CE754BBBEDD6501A1385E1B205C186E926ADED44287145E8897D4B2071') 400 }, 401 }; 402 return sm2KeyPairSpec; 403 } 404 405 async function sm2Test() { 406 let sm2KeyPairSpec = genSM2KeyPairSpec(); 407 let generatorBySpec = cryptoFramework.createAsyKeyGeneratorBySpec(sm2KeyPairSpec); 408 let keyPair = await generatorBySpec.generateKeyPair(); 409 let sm2CurveName = keyPair.priKey.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_CURVE_NAME_STR); 410 console.info('ECC_CURVE_NAME_STR: ' + sm2CurveName); // NID_sm2 411 } 412 ``` 413 414- 同步返回结果(调用方法[generateKeyPairSync](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#generatekeypairsync12)): 415 ```ts 416 import { cryptoFramework } from '@kit.CryptoArchitectureKit'; 417 418 function genSM2KeyPairSpec() { 419 let sm2CommonParamsSpec = cryptoFramework.ECCKeyUtil.genECCCommonParamsSpec('NID_sm2'); 420 let sm2KeyPairSpec: cryptoFramework.ECCKeyPairSpec = { 421 algName: "SM2", 422 specType: cryptoFramework.AsyKeySpecType.KEY_PAIR_SPEC, 423 params: sm2CommonParamsSpec, 424 sk: BigInt('0x6330B599ECD23ABDC74B9A5B7B5E00E553005F72743101C5FAB83AEB579B7074'), 425 pk: { 426 x: BigInt('0x67F3B850BDC0BA5D3A29D8A0883C4B17612AB84F87F18E28F77D824A115C02C4'), 427 y: BigInt('0xD48966CE754BBBEDD6501A1385E1B205C186E926ADED44287145E8897D4B2071') 428 }, 429 }; 430 return sm2KeyPairSpec; 431 } 432 function sm2TestSync() { 433 let sm2KeyPairSpec = genSM2KeyPairSpec(); 434 let generatorBySpec = cryptoFramework.createAsyKeyGeneratorBySpec(sm2KeyPairSpec); 435 try { 436 let keyPair = generatorBySpec.generateKeyPairSync(); 437 if (keyPair !== null) { 438 let sm2CurveName = keyPair.priKey.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_CURVE_NAME_STR); 439 console.info('ECC_CURVE_NAME_STR: ' + sm2CurveName); // NID_sm2 440 } else { 441 console.error('get key pair result fail!'); 442 } 443 } catch (e) { 444 console.error(`get key pair result fail, ${e.code}, ${e.message}`); 445 } 446 } 447 ``` 448