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