• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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