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