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