1# HUKS Development 2 3OpenHarmony Universal KeyStore (HUKS) provides KeyStore (KS) capabilities for applications, including key management and key cryptography operations. HUKS also provides APIs for applications to import or generate keys. 4 5> **NOTE** 6> 7> This document is based on API version 9 and applies only to ArkTS development. 8 9### Prerequisites 10 11The HUKS module must have been imported. 12 13```ts 14import huks from '@ohos.security.huks' 15``` 16 17### Generating a Key 18 19Generate a key for an application by specifying the alias and key parameters. 20 21> **NOTE** 22> 23> - When a key is used if the parameters passed in does not comply with the parameters passed in during the key generation, the parameter verification will fail. 24> 25> - If an optional parameter required by the algorithm is not passed in during the key generation process, it must be passed in when the key is used. 26 27**Supported Key Types** 28 29The following lists the mandatory parameters for key generation, including the key algorithm, key length, and key usage. 30 31| HUKS_ALG_ALGORITHM | HUKS_ALG_KEY_SIZE | HUKS_ALG_PURPOSE | 32| ------------------ | :----------------------------------------------------------- | ------------------------------------------------------------ | 33| HUKS_ALG_RSA | HUKS_RSA_KEY_SIZE_512 HUKS_RSA_KEY_SIZE_768 HUKS_RSA_KEY_SIZE_1024 HUKS_RSA_KEY_SIZE_2048 HUKS_RSA_KEY_SIZE_3072 HUKS_RSA_KEY_SIZE_4096 | HUKS_KEY_PURPOSE_ENCRYPT HUKS_KEY_PURPOSE_DECRYPT HUKS_KEY_PURPOSE_SIGN HUKS_KEY_PURPOSE_VERIFY | 34| HUKS_ALG_AES | HUKS_AES_KEY_SIZE_128 HUKS_AES_KEY_SIZE_192 HUKS_AES_KEY_SIZE_256 | HUKS_KEY_PURPOSE_ENCRYPT HUKS_KEY_PURPOSE_DECRYPT HUKS_KEY_PURPOSE_DERIVE | 35| HUKS_ALG_ECC | HUKS_ECC_KEY_SIZE_224 HUKS_ECC_KEY_SIZE_256 HUKS_ECC_KEY_SIZE_384 HUKS_ECC_KEY_SIZE_521 | HUKS_KEY_PURPOSE_SIGN HUKS_KEY_PURPOSE_VERIFY | 36| HUKS_ALG_X25519 | HUKS_CURVE25519_KEY_SIZE_256 | HUKS_KEY_PURPOSE_AGREE | 37| HUKS_ALG_ED25519 | HUKS_CURVE25519_KEY_SIZE_256 | HUKS_KEY_PURPOSE_SIGN HUKS_KEY_PURPOSE_VERIFY | 38| HUKS_ALG_DSA | HUKS_RSA_KEY_SIZE_1024 | HUKS_KEY_PURPOSE_SIGN HUKS_KEY_PURPOSE_VERIFY | 39| HUKS_ALG_DH | HUKS_DH_KEY_SIZE_2048 HUKS_DH_KEY_SIZE_3072 HUKS_DH_KEY_SIZE_4096 | HUKS_KEY_PURPOSE_AGREE | 40| HUKS_ALG_ECDH | HUKS_ECC_KEY_SIZE_224 HUKS_ECC_KEY_SIZE_256 HUKS_ECC_KEY_SIZE_384 HUKS_ECC_KEY_SIZE_521 | HUKS_KEY_PURPOSE_AGREE | 41| HUKS_ALG_SM2 | HUKS_SM2_KEY_SIZE_256 | HUKS_KEY_PURPOSE_SIGN HUKS_KEY_PURPOSE_VERIFY | 42| HUKS_ALG_SM4 | HUKS_SM4_KEY_SIZE_128 | HUKS_KEY_PURPOSE_ENCRYPT or HUKS_KEY_PURPOSE_DECRYPT | 43 44Before you get started, understand the following variables: 45 46| Parameter | Type | Mandatory| Description | 47| ---------------- | ----------- | ---- | ------------------------------------------------------------ | 48| genKeyAlias | string | Yes | Alias of the key generated. | 49| genKeyProperties | HuksOptions | Yes | Tags required for generating the key. The key algorithm, key usage, and key length are mandatory.| 50 51For details about the APIs, see [HUKS](../reference/apis/js-apis-huks.md). 52 53```ts 54/* Generate an ECC key of 256 bits. */ 55let keyAlias = 'keyAlias'; 56let properties = new Array(); 57// Mandatory parameter. 58properties[0] = { 59 tag: huks.HuksTag.HUKS_TAG_ALGORITHM, 60 value: huks.HuksKeyAlg.HUKS_ALG_ECC 61}; 62// Mandatory parameter. 63properties[1] = { 64 tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, 65 value: huks.HuksKeySize.HUKS_ECC_KEY_SIZE_256 66}; 67// Mandatory parameter. 68properties[2] = { 69 tag: huks.HuksTag.HUKS_TAG_PURPOSE, 70 value: 71 huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_SIGN | 72 huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_VERIFY 73}; 74// Optional parameter. 75properties[3] = { 76 tag: huks.HuksTag.HUKS_TAG_DIGEST, 77 value: huks.HuksKeyDigest.HUKS_DIGEST_SHA256 78}; 79let options = { 80 properties: properties 81}; 82try { 83 huks.generateKeyItem(keyAlias, options, function (error, data) { 84 if (error) { 85 console.error(`callback: generateKeyItem failed, code: ${error.code}, msg: ${error.message}`); 86 } else { 87 console.info(`callback: generateKeyItem key success`); 88 } 89 }); 90} catch (error) { 91 console.error(`callback: generateKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`); 92} 93``` 94 95 96 97### Key Import and Export 98 99The **HUKS** module allows the public key of its own asymmetric key (public and private key pair) to be exported based on the key alias. 100 101The **HUKS** module also supports import of external keys. Except the public keys of asymmetric keys, the keys imported into the HUKS cannot be exported in their lifecycle. If the alias of the key to be imported already exists in HUKS, the newly imported key will overwrite the existing one. 102 103The development procedure is as follows: 104 1051. Generate a key. 1062. Export the key. 1073. Import the key. 108 109**Supported Types of Keys to Import** 110 111AES128, AES192, AES256, RSA512, RSA768, RSA1024, RSA2048, RSA3072, RSA4096, HmacSHA1, HmacSHA224, HmacSHA256, HmacSHA384, HmacSHA512, ECC224, ECC256, ECC384, ECC521, Curve25519, DSA, SM2, SM3, SM4 112 113**Supported Types of Keys to Export** 114 115RSA512, RSA768, RSA1024, RSA2048, RSA3072, RSA4096, ECC224, ECC256, ECC384, ECC521, Curve25519, DSA, SM2 116 117> **NOTE**<br> 118> 119> The key alias cannot exceed 64 bytes. 120 121Before you get started, understand the following variables: 122 123| Parameter | Type | Mandatory| Description | 124| -------------- | ----------- | ---- | ------------------------ | 125| exportKeyAlias | string | Yes | Alias of the key to generate. | 126| importKeyAlias | string | Yes | Alias of the key to import. | 127| huksOptions | HuksOptions | Yes | Tags required for generating the key.| 128| encryptOptions | HuksOptions | Yes | Tags required for importing the key.| 129 130For details about the APIs, see [HUKS](../reference/apis/js-apis-huks.md). 131 132**Example** 133 134```ts 135/* Export an RSA512 key and import DH2048, RSA512, x25519, and ECC256 keys.*/ 136import huks from '@ohos.security.huks'; 137 138function StringToUint8Array(str) { 139 let arr = []; 140 for (let i = 0, j = str.length; i < j; ++i) { 141 arr.push(str.charCodeAt(i)); 142 } 143 return new Uint8Array(arr); 144} 145 146function Uint8ArrayToString(fileData) { 147 let dataString = ''; 148 for (let i = 0; i < fileData.length; i++) { 149 dataString += String.fromCharCode(fileData[i]); 150 } 151 return dataString; 152} 153 154function Uint32ToUint8(value) { 155 let arr = new Uint8Array(4 * value.length); 156 for (let i = 0, j = value.length; i < j; i++) { 157 arr[i * 4+3] = (value[i] >> 24) & 0xFF; 158 arr[i * 4+2] = (value[i] >> 16) & 0xFF; 159 arr[i * 4+1] = (value[i] >> 8) & 0xFF; 160 arr[i*4] = (value[i]) & 0xFF; 161 } 162 return arr; 163} 164 165async function publicGenKeyFunc(keyAlias: string, huksOptions: huks.HuksOptions) { 166 console.info(`enter callback generateKeyItem`); 167 try { 168 await generateKeyItem(keyAlias, huksOptions) 169 .then((data) => { 170 console.info(`callback: generateKeyItem success, data = ${JSON.stringify(data)}`); 171 }) 172 .catch(error => { 173 console.error(`callback: generateKeyItem failed, code: ${error.code}, msg: ${error.message}`); 174 }); 175 } catch (error) { 176 console.error(`callback: generateKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`); 177 } 178} 179 180function generateKeyItem(keyAlias: string, huksOptions: huks.HuksOptions) { 181 return new Promise((resolve, reject) => { 182 try { 183 huks.generateKeyItem(keyAlias, huksOptions, function (error, data) { 184 if (error) { 185 reject(error); 186 } else { 187 resolve(data); 188 } 189 }); 190 } catch (error) { 191 throw (error); 192 } 193 }); 194} 195 196async function publicExportKeyFunc(keyAlias: string, huksOptions: huks.HuksOptions) { 197 console.info(`enter callback export`); 198 try { 199 await exportKeyItem(keyAlias, huksOptions) 200 .then((data) => { 201 console.info(`callback: exportKeyItem success, data = ${JSON.stringify(data)}`); 202 }) 203 .catch(error => { 204 console.error(`callback: exportKeyItem failed, code: ${error.code}, msg: ${error.message}`); 205 }); 206 } catch (error) { 207 console.error(`callback: exportKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`); 208 } 209} 210 211function exportKeyItem(keyAlias: string, huksOptions: huks.HuksOptions): Promise<huks.HuksReturnResult> { 212 return new Promise((resolve, reject) => { 213 try { 214 huks.exportKeyItem(keyAlias, huksOptions, function (error, data) { 215 if (error) { 216 reject(error); 217 } else { 218 resolve(data); 219 } 220 }); 221 } catch (error) { 222 throw (error); 223 } 224 }); 225} 226 227async function publicImportKeyFunc(keyAlias: string, huksOptions: huks.HuksOptions) { 228 console.info(`enter promise importKeyItem`); 229 try { 230 await importKeyItem(keyAlias, huksOptions) 231 .then((data) => { 232 console.info(`callback: importKeyItem success, data = ${JSON.stringify(data)}`); 233 }) 234 .catch(error => { 235 console.error(`callback: importKeyItem failed, code: ${error.code}, msg: ${error.message}`); 236 }); 237 } catch (error) { 238 console.error(`callback: importKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`); 239 } 240} 241 242function importKeyItem(keyAlias: string, huksOptions: huks.HuksOptions) { 243 return new Promise((resolve, reject) => { 244 try { 245 huks.importKeyItem(keyAlias, huksOptions, function (error, data) { 246 if (error) { 247 reject(error); 248 } else { 249 resolve(data); 250 } 251 }); 252 } catch (error) { 253 throw (error); 254 } 255 }); 256} 257 258async function publicDeleteKeyFunc(keyAlias: string, huksOptions: huks.HuksOptions) { 259 console.info(`enter callback deleteKeyItem`); 260 try { 261 await deleteKeyItem(keyAlias, huksOptions) 262 .then((data) => { 263 console.info(`callback: deleteKeyItem key success, data = ${JSON.stringify(data)}`); 264 }) 265 .catch(error => { 266 console.error(`callback: deleteKeyItem failed, code: ${error.code}, msg: ${error.message}`); 267 }); 268 } catch (error) { 269 console.error(`callback: deleteKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`); 270 } 271} 272 273function deleteKeyItem(keyAlias: string, huksOptions: huks.HuksOptions) { 274 return new Promise((resolve, reject) => { 275 try { 276 huks.deleteKeyItem(keyAlias, huksOptions, function (error, data) { 277 if (error) { 278 reject(error); 279 } else { 280 resolve(data); 281 } 282 }); 283 } catch (error) { 284 throw (error); 285 } 286 }); 287} 288 289// Export the RSA key. 290async function testExportRsa() { 291 let exportKeyAlias = 'export_rsa_key'; 292 /* Configure the parameters for generating the key. */ 293 let exportProperties = new Array(); 294 exportProperties[0] = { 295 tag: huks.HuksTag.HUKS_TAG_ALGORITHM, 296 value: huks.HuksKeyAlg.HUKS_ALG_RSA 297 } 298 exportProperties[1] = { 299 tag: huks.HuksTag.HUKS_TAG_PURPOSE, 300 value: 301 huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT | 302 huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT 303 } 304 exportProperties[2] = { 305 tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, 306 value: huks.HuksKeySize.HUKS_RSA_KEY_SIZE_512 307 } 308 exportProperties[3] = { 309 tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE, 310 value: huks.HuksCipherMode.HUKS_MODE_ECB 311 } 312 exportProperties[4] = { 313 tag: huks.HuksTag.HUKS_TAG_PADDING, 314 value: huks.HuksKeyPadding.HUKS_PADDING_PKCS1_V1_5 315 } 316 exportProperties[5] = { 317 tag: huks.HuksTag.HUKS_TAG_DIGEST, 318 value: huks.HuksKeyDigest.HUKS_DIGEST_SHA256 319 } 320 let huksOptions = { 321 properties: exportProperties, 322 inData: new Uint8Array(new Array()) 323 } 324 325 /* Generate a key. */ 326 await publicGenKeyFunc(exportKeyAlias, huksOptions); 327 328 /* Export the key. */ 329 await publicExportKeyFunc(exportKeyAlias, huksOptions); 330 await publicDeleteKeyFunc(exportKeyAlias, huksOptions); 331} 332 333// DH key 334let g_dhPubData = new Uint8Array([ 335 0x8a, 0xbf, 0x16, 0x67, 0x1b, 0x92, 0x4b, 0xf2, 0xe0, 0x02, 0xc5, 0x1f, 0x84, 0x00, 0xf8, 0x93, 336 0x0f, 0x74, 0xe7, 0x0f, 0xba, 0x78, 0x30, 0xa8, 0x2d, 0x92, 0xef, 0x9b, 0x80, 0xeb, 0x76, 0xea, 337 0x26, 0x74, 0x72, 0x63, 0x6a, 0x27, 0xc3, 0x8f, 0xcf, 0xbe, 0x82, 0xa2, 0x8b, 0xdc, 0x65, 0x58, 338 0xe3, 0xff, 0x29, 0x97, 0xad, 0xb3, 0x4a, 0x2c, 0x50, 0x08, 0xb5, 0x68, 0xe1, 0x90, 0x5a, 0xdc, 339 0x48, 0xb3, 0x6b, 0x7a, 0xce, 0x2e, 0x81, 0x3d, 0x38, 0x35, 0x59, 0xdc, 0x39, 0x8a, 0x97, 0xfe, 340 0x20, 0x86, 0x20, 0xdb, 0x55, 0x38, 0x23, 0xca, 0xb5, 0x5b, 0x61, 0x00, 0xdc, 0x45, 0xe2, 0xa1, 341 0xf4, 0x1e, 0x7b, 0x01, 0x7a, 0x84, 0x36, 0xa4, 0xa8, 0x1c, 0x0d, 0x3d, 0xde, 0x57, 0x66, 0x73, 342 0x4e, 0xaf, 0xee, 0xb0, 0xb0, 0x69, 0x0c, 0x13, 0xba, 0x76, 0xff, 0x2e, 0xb6, 0x16, 0xf9, 0xfc, 343 0xd6, 0x09, 0x5b, 0xc7, 0x37, 0x65, 0x84, 0xd5, 0x82, 0x8a, 0xd7, 0x5b, 0x57, 0xe3, 0x0e, 0x89, 344 0xbe, 0x05, 0x05, 0x55, 0x2e, 0x9f, 0x94, 0x8a, 0x53, 0xdc, 0xb7, 0x00, 0xb2, 0x6a, 0x7b, 0x8e, 345 0xdf, 0x6e, 0xa4, 0x6d, 0x13, 0xb6, 0xbc, 0xaa, 0x8e, 0x44, 0x11, 0x50, 0x32, 0x91, 0x56, 0xa2, 346 0x22, 0x3f, 0x2f, 0x08, 0xbb, 0x4d, 0xbb, 0x69, 0xe6, 0xb1, 0xc2, 0x70, 0x79, 0x15, 0x54, 0xad, 347 0x4a, 0x29, 0xef, 0xa9, 0x3e, 0x64, 0x8d, 0xf1, 0x90, 0xf4, 0xa7, 0x93, 0x8c, 0x7a, 0x02, 0x4d, 348 0x38, 0x1f, 0x58, 0xb8, 0xe4, 0x7c, 0xe1, 0x66, 0x1c, 0x72, 0x30, 0xf3, 0x4c, 0xf4, 0x24, 0xd1, 349 0x2d, 0xb7, 0xf1, 0x5a, 0x0f, 0xb8, 0x20, 0xc5, 0x90, 0xe5, 0xca, 0x45, 0x84, 0x5c, 0x08, 0x08, 350 0xbf, 0xf9, 0x69, 0x41, 0xf5, 0x49, 0x85, 0x31, 0x35, 0x14, 0x69, 0x12, 0x57, 0x9c, 0xc8, 0xb7]); 351let g_dhPriData = new Uint8Array([ 352 0x01, 0xbc, 0xa7, 0x42, 0x25, 0x79, 0xc5, 0xaf, 0x0f, 0x9c, 0xde, 0x00, 0x3b, 0x58, 0x5c, 0xd1, 353 0x1d, 0x7b, 0xcf, 0x66, 0xcd, 0xa9, 0x10, 0xae, 0x92, 0x2d, 0x3c, 0xb7, 0xf3]); 354let g_dhX509PubData = new Uint8Array([ 355 0x30, 0x82, 0x02, 0x29, 0x30, 0x82, 0x01, 0x1b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 356 0x01, 0x03, 0x01, 0x30, 0x82, 0x01, 0x0c, 0x02, 0x82, 0x01, 0x01, 0x00, 0xff, 0xff, 0xff, 0xff, 357 0xff, 0xff, 0xff, 0xff, 0xad, 0xf8, 0x54, 0x58, 0xa2, 0xbb, 0x4a, 0x9a, 0xaf, 0xdc, 0x56, 0x20, 358 0x27, 0x3d, 0x3c, 0xf1, 0xd8, 0xb9, 0xc5, 0x83, 0xce, 0x2d, 0x36, 0x95, 0xa9, 0xe1, 0x36, 0x41, 359 0x14, 0x64, 0x33, 0xfb, 0xcc, 0x93, 0x9d, 0xce, 0x24, 0x9b, 0x3e, 0xf9, 0x7d, 0x2f, 0xe3, 0x63, 360 0x63, 0x0c, 0x75, 0xd8, 0xf6, 0x81, 0xb2, 0x02, 0xae, 0xc4, 0x61, 0x7a, 0xd3, 0xdf, 0x1e, 0xd5, 361 0xd5, 0xfd, 0x65, 0x61, 0x24, 0x33, 0xf5, 0x1f, 0x5f, 0x06, 0x6e, 0xd0, 0x85, 0x63, 0x65, 0x55, 362 0x3d, 0xed, 0x1a, 0xf3, 0xb5, 0x57, 0x13, 0x5e, 0x7f, 0x57, 0xc9, 0x35, 0x98, 0x4f, 0x0c, 0x70, 363 0xe0, 0xe6, 0x8b, 0x77, 0xe2, 0xa6, 0x89, 0xda, 0xf3, 0xef, 0xe8, 0x72, 0x1d, 0xf1, 0x58, 0xa1, 364 0x36, 0xad, 0xe7, 0x35, 0x30, 0xac, 0xca, 0x4f, 0x48, 0x3a, 0x79, 0x7a, 0xbc, 0x0a, 0xb1, 0x82, 365 0xb3, 0x24, 0xfb, 0x61, 0xd1, 0x08, 0xa9, 0x4b, 0xb2, 0xc8, 0xe3, 0xfb, 0xb9, 0x6a, 0xda, 0xb7, 366 0x60, 0xd7, 0xf4, 0x68, 0x1d, 0x4f, 0x42, 0xa3, 0xde, 0x39, 0x4d, 0xf4, 0xae, 0x56, 0xed, 0xe7, 367 0x63, 0x72, 0xbb, 0x19, 0x0b, 0x07, 0xa7, 0xc8, 0xee, 0x0a, 0x6d, 0x70, 0x9e, 0x02, 0xfc, 0xe1, 368 0xcd, 0xf7, 0xe2, 0xec, 0xc0, 0x34, 0x04, 0xcd, 0x28, 0x34, 0x2f, 0x61, 0x91, 0x72, 0xfe, 0x9c, 369 0xe9, 0x85, 0x83, 0xff, 0x8e, 0x4f, 0x12, 0x32, 0xee, 0xf2, 0x81, 0x83, 0xc3, 0xfe, 0x3b, 0x1b, 370 0x4c, 0x6f, 0xad, 0x73, 0x3b, 0xb5, 0xfc, 0xbc, 0x2e, 0xc2, 0x20, 0x05, 0xc5, 0x8e, 0xf1, 0x83, 371 0x7d, 0x16, 0x83, 0xb2, 0xc6, 0xf3, 0x4a, 0x26, 0xc1, 0xb2, 0xef, 0xfa, 0x88, 0x6b, 0x42, 0x38, 372 0x61, 0x28, 0x5c, 0x97, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, 0x01, 0x02, 0x02, 373 0x02, 0x00, 0xe1, 0x03, 0x82, 0x01, 0x06, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, 0x8a, 0xbf, 0x16, 374 0x67, 0x1b, 0x92, 0x4b, 0xf2, 0xe0, 0x02, 0xc5, 0x1f, 0x84, 0x00, 0xf8, 0x93, 0x0f, 0x74, 0xe7, 375 0x0f, 0xba, 0x78, 0x30, 0xa8, 0x2d, 0x92, 0xef, 0x9b, 0x80, 0xeb, 0x76, 0xea, 0x26, 0x74, 0x72, 376 0x63, 0x6a, 0x27, 0xc3, 0x8f, 0xcf, 0xbe, 0x82, 0xa2, 0x8b, 0xdc, 0x65, 0x58, 0xe3, 0xff, 0x29, 377 0x97, 0xad, 0xb3, 0x4a, 0x2c, 0x50, 0x08, 0xb5, 0x68, 0xe1, 0x90, 0x5a, 0xdc, 0x48, 0xb3, 0x6b, 378 0x7a, 0xce, 0x2e, 0x81, 0x3d, 0x38, 0x35, 0x59, 0xdc, 0x39, 0x8a, 0x97, 0xfe, 0x20, 0x86, 0x20, 379 0xdb, 0x55, 0x38, 0x23, 0xca, 0xb5, 0x5b, 0x61, 0x00, 0xdc, 0x45, 0xe2, 0xa1, 0xf4, 0x1e, 0x7b, 380 0x01, 0x7a, 0x84, 0x36, 0xa4, 0xa8, 0x1c, 0x0d, 0x3d, 0xde, 0x57, 0x66, 0x73, 0x4e, 0xaf, 0xee, 381 0xb0, 0xb0, 0x69, 0x0c, 0x13, 0xba, 0x76, 0xff, 0x2e, 0xb6, 0x16, 0xf9, 0xfc, 0xd6, 0x09, 0x5b, 382 0xc7, 0x37, 0x65, 0x84, 0xd5, 0x82, 0x8a, 0xd7, 0x5b, 0x57, 0xe3, 0x0e, 0x89, 0xbe, 0x05, 0x05, 383 0x55, 0x2e, 0x9f, 0x94, 0x8a, 0x53, 0xdc, 0xb7, 0x00, 0xb2, 0x6a, 0x7b, 0x8e, 0xdf, 0x6e, 0xa4, 384 0x6d, 0x13, 0xb6, 0xbc, 0xaa, 0x8e, 0x44, 0x11, 0x50, 0x32, 0x91, 0x56, 0xa2, 0x22, 0x3f, 0x2f, 385 0x08, 0xbb, 0x4d, 0xbb, 0x69, 0xe6, 0xb1, 0xc2, 0x70, 0x79, 0x15, 0x54, 0xad, 0x4a, 0x29, 0xef, 386 0xa9, 0x3e, 0x64, 0x8d, 0xf1, 0x90, 0xf4, 0xa7, 0x93, 0x8c, 0x7a, 0x02, 0x4d, 0x38, 0x1f, 0x58, 387 0xb8, 0xe4, 0x7c, 0xe1, 0x66, 0x1c, 0x72, 0x30, 0xf3, 0x4c, 0xf4, 0x24, 0xd1, 0x2d, 0xb7, 0xf1, 388 0x5a, 0x0f, 0xb8, 0x20, 0xc5, 0x90, 0xe5, 0xca, 0x45, 0x84, 0x5c, 0x08, 0x08, 0xbf, 0xf9, 0x69, 389 0x41, 0xf5, 0x49, 0x85, 0x31, 0x35, 0x14, 0x69, 0x12, 0x57, 0x9c, 0xc8, 0xb7]); 390 391// X25519 key 392let g_x25519PubData = new Uint8Array([ 393 0x9c, 0xf6, 0x7a, 0x8d, 0xce, 0xc2, 0x7f, 0xa7, 0xd9, 0xfd, 0xf1, 0xad, 0xac, 0xf0, 0xb3, 0x8c, 394 0xe8, 0x16, 0xa2, 0x65, 0xcc, 0x18, 0x55, 0x60, 0xcd, 0x2f, 0xf5, 0xe5, 0x72, 0xc9, 0x3c, 0x54]); 395// X25519 public key 396let g_x25519PriData = new Uint8Array([ 397 0x20, 0xd5, 0xbb, 0x54, 0x6f, 0x1f, 0x00, 0x30, 0x4e, 0x33, 0x38, 0xb9, 0x8e, 0x6a, 0xdf, 0xad, 398 0x33, 0x6f, 0x51, 0x23, 0xff, 0x4d, 0x95, 0x26, 0xdc, 0xb0, 0x74, 0xb2, 0x5c, 0x7e, 0x85, 0x6c]); 399 400// RSA key 401let g_nData = new Uint8Array([ 402 0xb6, 0xd8, 0x9b, 0x33, 0x78, 0xa2, 0x63, 0x21, 0x84, 0x47, 0xa1, 0x72, 0 x3d, 0x73, 0x10, 0xbd, 403 0xe9, 0x5d, 0x78, 0x44, 0x3d, 0x80, 0x18, 0x12, 0x60, 0xed, 0x29, 0x3e, 0xc7, 0x23, 0x0d, 0x3f, 404 0x02, 0x59, 0x28, 0xe2, 0x8f, 0x83, 0xdf, 0x37, 0x4b, 0x77, 0xce, 0x5f, 0xb6, 0xcd, 0x61, 0x72, 405 0xee, 0x01, 0xe2, 0x37, 0x4d, 0xfd, 0x4f, 0x39, 0xcf, 0xbd, 0xff, 0x84, 0x57, 0x44, 0xa5, 0x03]); 406let g_eData = new Uint8Array([0x01, 0x00, 0x01]); 407let g_dData = new Uint8Array([ 408 0x35, 0x63, 0x89, 0xed, 0xbd, 0x8b, 0xac, 0xe6, 0x5c, 0x79, 0x8d, 0xea, 0x8d, 0x86, 0xcb, 0x9c, 409 0xa8, 0x47, 0x62, 0x96, 0x8a, 0x5e, 0x9c, 0xa8, 0xc1, 0x24, 0x7e, 0xa6, 0x95, 0xfe, 0xe6, 0x1e, 410 0xc0, 0xf3, 0x29, 0x76, 0xbb, 0x4d, 0xe4, 0xbc, 0x78, 0x64, 0xe1, 0x79, 0xcd, 0x8a, 0x45, 0xac, 411 0x5c, 0x88, 0xea, 0xb4, 0x10, 0xd8, 0x90, 0x65, 0x7b, 0x94, 0xe8, 0x87, 0x30, 0x2a, 0x04, 0x01]); 412let g_pubData = new Uint8Array([ 413 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 414 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41, 0x00, 0x9e, 0x93, 0x57, 0xc4, 0xab, 0xde, 0x30, 415 0xc5, 0x3f, 0x3b, 0x33, 0xa6, 0xdc, 0x4a, 0xdb, 0xbf, 0x12, 0x9e, 0x5d, 0xc4, 0xba, 0x0e, 0x15, 416 0x06, 0x41, 0xd8, 0x96, 0x43, 0xca, 0xc5, 0xea, 0x9f, 0xdd, 0xa0, 0x2a, 0xf1, 0x53, 0x46, 0x14, 417 0x36, 0x7a, 0xab, 0xbc, 0x92, 0x1b, 0x07, 0xc6, 0x9a, 0x7d, 0x0c, 0xd0, 0xa0, 0x0f, 0x31, 0xd5, 418 0x38, 0x84, 0x6c, 0x08, 0xcb, 0x9b, 0x10, 0xa6, 0x4d, 0x02, 0x03, 0x01, 0x00, 0x01]); 419 420// ECC key 421let g_eccXData = new Uint8Array([ 422 0xa5, 0xb8, 0xa3, 0x78, 0x1d, 0x6d, 0x76, 0xe0, 0xb3, 0xf5, 0x6f, 0x43, 0x9d, 0xcf, 0x60, 0xf6, 423 0x0b, 0x3f, 0x64, 0x45, 0xa8, 0x3f, 0x1a, 0x96, 0xf1, 0xa1, 0xa4, 0x5d, 0x3e, 0x2c, 0x3f, 0x13]); 424let g_eccYData = new Uint8Array([ 425 0xd7, 0x81, 0xf7, 0x2a, 0xb5, 0x8d, 0x19, 0x3d, 0x9b, 0x96, 0xc7, 0x6a, 0x10, 0xf0, 0xaa, 0xbc, 426 0x91, 0x6f, 0x4d, 0xa7, 0x09, 0xb3, 0x57, 0x88, 0x19, 0x6f, 0x00, 0x4b, 0xad, 0xee, 0x34, 0x35]); 427let g_eccZData = new Uint8Array([ 428 0xfb, 0x8b, 0x9f, 0x12, 0xa0, 0x83, 0x19, 0xbe, 0x6a, 0x6f, 0x63, 0x2a, 0x7c, 0x86, 0xba, 0xca, 429 0x64, 0x0b, 0x88, 0x96, 0xe2, 0xfa, 0x77, 0xbc, 0x71, 0xe3, 0x0f, 0x0f, 0x9e, 0x3c, 0xe5, 0xf9]); 430let g_eccPubData = new Uint8Array([ 431 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 432 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0xa5, 0xb8, 0xa3, 0x78, 0x1d, 433 0x6d, 0x76, 0xe0, 0xb3, 0xf5, 0x6f, 0x43, 0x9d, 0xcf, 0x60, 0xf6, 0x0b, 0x3f, 0x64, 0x45, 0xa8, 434 0x3f, 0x1a, 0x96, 0xf1, 0xa1, 0xa4, 0x5d, 0x3e, 0x2c, 0x3f, 0x13, 0xd7, 0x81, 0xf7, 0x2a, 0xb5, 435 0x8d, 0x19, 0x3d, 0x9b, 0x96, 0xc7, 0x6a, 0x10, 0xf0, 0xaa, 0xbc, 0x91, 0x6f, 0x4d, 0xa7, 0x09, 436 0xb3, 0x57, 0x88, 0x19, 0x6f, 0x00, 0x4b, 0xad, 0xee, 0x34, 0x35]); 437 438// Import the DH2048 key. 439async function ImportDhTest(alg, keyType) { 440 let importKeyAlias = 'import_dh_key'; 441 let properties = new Array(); 442 properties[0] = { 443 tag: huks.HuksTag.HUKS_TAG_ALGORITHM, 444 value: huks.HuksKeyAlg.HUKS_ALG_DH 445 } 446 properties[1] = { 447 tag: huks.HuksTag.HUKS_TAG_PURPOSE, 448 value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_AGREE 449 } 450 properties[2] = { 451 tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, 452 value: huks.HuksKeySize.HUKS_DH_KEY_SIZE_2048 453 } 454 properties[3] = { 455 tag: huks.HuksTag.HUKS_TAG_IMPORT_KEY_TYPE, 456 value: huks.HuksImportKeyType.HUKS_KEY_TYPE_PUBLIC_KEY 457 } 458 properties[4] = { 459 tag: huks.HuksTag.HUKS_TAG_DIGEST, 460 value: huks.HuksKeyDigest.HUKS_DIGEST_SHA256 461 } 462 let huksOptions = { 463 properties: properties, 464 inData: new Uint8Array(new Array()) 465 } 466 huksOptions.properties[0].value = alg; 467 huksOptions.properties[3].value = keyType; 468 469 // Compare the key types. 470 if (huksOptions.properties[3].value === huks.HuksImportKeyType.HUKS_KEY_TYPE_KEY_PAIR) { 471 /* Concatenate the huksOptions.inData field with a non-public key in the following format: 472 * keyAlg type (4 bytes) + key_dh length (4 bytes) + 473 * g_dhPubData length (4 bytes) + g_dhPriData length (4 bytes) + 474 * Reserved size (4 bytes) + g_dhPubData + g_dhPriData 475 */ 476 // Key pair 477 let Material = new Uint32Array([huks.HuksKeyAlg.HUKS_ALG_DH, huks.HuksKeySize.HUKS_DH_KEY_SIZE_2048, g_dhPubData.length, g_dhPriData.length, 0]); 478 let u8Material = Uint32ToUint8(Material); 479 let strMaterial = Uint8ArrayToString(u8Material); 480 481 let strXData = strMaterial.concat(Uint8ArrayToString(g_dhPubData)); 482 let strData = strXData.concat(Uint8ArrayToString(g_dhPriData)); 483 huksOptions.inData = StringToUint8Array(strData); 484 } else if (huksOptions.properties[3].value === huks.HuksImportKeyType.HUKS_KEY_TYPE_PRIVATE_KEY) { 485 // Private key 486 let Material = new Uint32Array([huks.HuksKeyAlg.HUKS_ALG_DH, huks.HuksKeySize.HUKS_DH_KEY_SIZE_2048, 0, g_dhPriData.length, 0]); 487 let u8Material = Uint32ToUint8(Material); 488 let strMaterial = Uint8ArrayToString(u8Material); 489 490 let strData = strMaterial.concat(Uint8ArrayToString(g_dhPriData)); 491 huksOptions.inData = StringToUint8Array(strData); 492 } else if (huksOptions.properties[3].value === huks.HuksImportKeyType.HUKS_KEY_TYPE_PUBLIC_KEY) { 493 // Public key 494 huksOptions.inData = g_dhX509PubData; 495 } 496 497 await publicImportKeyFunc(importKeyAlias, huksOptions); 498 await publicDeleteKeyFunc(importKeyAlias, huksOptions); 499} 500 501// Import the ECC256 key. 502async function ImportEccTest(alg, keyType) { 503 let importKeyAlias = 'import_ecc_key'; 504 let properties = new Array(); 505 properties[0] = { 506 tag: huks.HuksTag.HUKS_TAG_ALGORITHM, 507 value: huks.HuksKeyAlg.HUKS_ALG_ECC 508 } 509 properties[1] = { 510 tag: huks.HuksTag.HUKS_TAG_PURPOSE, 511 value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_AGREE 512 } 513 properties[2] = { 514 tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, 515 value: huks.HuksKeySize.HUKS_ECC_KEY_SIZE_256 516 } 517 properties[3] = { 518 tag: huks.HuksTag.HUKS_TAG_IMPORT_KEY_TYPE, 519 value: huks.HuksImportKeyType.HUKS_KEY_TYPE_KEY_PAIR 520 } 521 properties[4] = { 522 tag: huks.HuksTag.HUKS_TAG_DIGEST, 523 value: huks.HuksKeyDigest.HUKS_DIGEST_SHA256 524 } 525 let huksOptions = { 526 properties: properties, 527 inData: new Uint8Array(new Array()) 528 } 529 huksOptions.properties[0].value = alg; 530 huksOptions.properties[3].value = keyType; 531 532 // Compare the key types. 533 if (huksOptions.properties[3].value === huks.HuksImportKeyType.HUKS_KEY_TYPE_KEY_PAIR) { 534 /* Concatenate the huksOptions.inData field with a non-public key in the following format: 535 * keyAlg type (4 bytes) + key_ecc length (4 bytes) + 536 * g_eccXData length (4 bytes) + g_eccYData length (4 bytes) + 537 * g_eccZData length (4 bytes) + g_eccXData + 538 * g_eccYData + g_eccZData 539 */ 540 // Key pair 541 let Material = new Uint32Array([huks.HuksKeyAlg.HUKS_ALG_ECC, huks.HuksKeySize.HUKS_ECC_KEY_SIZE_256, g_eccXData.length, g_eccYData.length, g_eccZData.length]); 542 let u8Material = Uint32ToUint8(Material); 543 let strMaterial = Uint8ArrayToString(u8Material); 544 545 let strXData = strMaterial.concat(Uint8ArrayToString(g_eccXData)); 546 let strYData = strXData.concat(Uint8ArrayToString(g_eccYData)); 547 let strData = strYData.concat(Uint8ArrayToString(g_eccZData)); 548 huksOptions.inData = StringToUint8Array(strData); 549 } else if (huksOptions.properties[3].value === huks.HuksImportKeyType.HUKS_KEY_TYPE_PRIVATE_KEY) { 550 // Private key 551 huksOptions.properties[3].value == huks.HuksImportKeyType.HUKS_KEY_TYPE_PRIVATE_KEY 552 let Material = new Uint32Array([huks.HuksKeyAlg.HUKS_ALG_ECC, huks.HuksKeySize.HUKS_ECC_KEY_SIZE_256, 0, 0, g_eccZData.length]); 553 let u8Material = Uint32ToUint8(Material); 554 let strMaterial = Uint8ArrayToString(u8Material); 555 556 let strData = strMaterial.concat(Uint8ArrayToString(g_eccZData)); 557 huksOptions.inData = StringToUint8Array(strData); 558 } else if (huksOptions.properties[3].value === huks.HuksImportKeyType.HUKS_KEY_TYPE_PUBLIC_KEY) { 559 // Public key 560 huksOptions.inData = g_eccPubData; 561 } 562 563 await publicImportKeyFunc(importKeyAlias, huksOptions); 564 await publicDeleteKeyFunc(importKeyAlias, huksOptions); 565} 566 567// Import the RSA512 key. 568async function ImportRsaTest(alg, keyType) { 569 let importKeyAlias = 'import_rsa_key'; 570 let properties = new Array(); 571 properties[0] = { 572 tag: huks.HuksTag.HUKS_TAG_ALGORITHM, 573 value: huks.HuksKeyAlg.HUKS_ALG_RSA 574 } 575 properties[1] = { 576 tag: huks.HuksTag.HUKS_TAG_PURPOSE, 577 value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_SIGN 578 } 579 properties[2] = { 580 tag: huks.HuksTag.HUKS_TAG_DIGEST, 581 value: huks.HuksKeyDigest.HUKS_DIGEST_SHA256 582 } 583 properties[3] = { 584 tag: huks.HuksTag.HUKS_TAG_PADDING, 585 value: huks.HuksKeyPadding.HUKS_PADDING_PSS 586 } 587 properties[4] = { 588 tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, 589 value: huks.HuksKeySize.HUKS_RSA_KEY_SIZE_512 590 } 591 properties[5] = { 592 tag: huks.HuksTag.HUKS_TAG_IMPORT_KEY_TYPE, 593 value: huks.HuksImportKeyType.HUKS_KEY_TYPE_KEY_PAIR 594 } 595 let huksOptions = { 596 properties: properties, 597 inData: new Uint8Array(new Array()) 598 } 599 huksOptions.properties[0].value = alg; 600 huksOptions.properties[3].value = keyType; 601 602 // Compare the key types. 603 if (huksOptions.properties[5].value === huks.HuksImportKeyType.HUKS_KEY_TYPE_KEY_PAIR) { 604 /* Concatenate the huksOptions.inData field with a non-public key in the following format: 605 * keyAlg type (4 bytes) + key_rsa length (4 bytes) + 606 * g_nData length (4 bytes) + g_eData length (4 bytes) + 607 * g_dData length (4 bytes) + g_nData + 608 * g_eData + g_dData 609 */ 610 // Key pair 611 let Material = new Uint32Array([huks.HuksKeyAlg.HUKS_ALG_RSA, huks.HuksKeySize.HUKS_RSA_KEY_SIZE_512, g_nData.length, g_eData.length, g_dData.length]); 612 let u8Material = Uint32ToUint8(Material); 613 let strMaterial = Uint8ArrayToString(u8Material); 614 let strNData = strMaterial.concat(Uint8ArrayToString(g_nData)); 615 let strEData = strNData.concat(Uint8ArrayToString(g_eData)); 616 let strData = strEData.concat(Uint8ArrayToString(g_dData)); 617 huksOptions.inData = StringToUint8Array(strData); 618 } else if (huksOptions.properties[5].value === huks.HuksImportKeyType.HUKS_KEY_TYPE_PRIVATE_KEY) { 619 // Private key 620 let Material = new Uint32Array([huks.HuksKeyAlg.HUKS_ALG_RSA, huks.HuksKeySize.HUKS_RSA_KEY_SIZE_512, g_nData.length, 0, g_dData.length]); 621 let u8Material = Uint32ToUint8(Material); 622 let strMaterial = Uint8ArrayToString(u8Material); 623 let strNData = strMaterial.concat(Uint8ArrayToString(g_nData)); 624 let strData = strNData.concat(Uint8ArrayToString(g_dData)); 625 huksOptions.inData = StringToUint8Array(strData); 626 } else if (huksOptions.properties[5].value === huks.HuksImportKeyType.HUKS_KEY_TYPE_PUBLIC_KEY) { 627 // Public key 628 huksOptions.inData = g_pubData; 629 } 630 await publicImportKeyFunc(importKeyAlias, huksOptions); 631 await publicDeleteKeyFunc(importKeyAlias, huksOptions); 632} 633 634// Import the X25519 key. 635async function ImportX25519Test(alg, keyType) { 636 let importKeyAlias = 'import_x25519_key'; 637 let properties = new Array(); 638 properties[0] = { 639 tag: huks.HuksTag.HUKS_TAG_ALGORITHM, 640 value: huks.HuksKeyAlg.HUKS_ALG_X25519 641 } 642 properties[1] = { 643 tag: huks.HuksTag.HUKS_TAG_PURPOSE, 644 value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_AGREE 645 } 646 properties[2] = { 647 tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, 648 value: huks.HuksKeySize.HUKS_CURVE25519_KEY_SIZE_256 649 } 650 properties[3] = { 651 tag: huks.HuksTag.HUKS_TAG_IMPORT_KEY_TYPE, 652 value: huks.HuksImportKeyType.HUKS_KEY_TYPE_KEY_PAIR 653 } 654 properties[4] = { 655 tag: huks.HuksTag.HUKS_TAG_DIGEST, 656 value: huks.HuksKeyDigest.HUKS_DIGEST_SHA256 657 } 658 let huksOptions = { 659 properties: properties, 660 inData: new Uint8Array(new Array()) 661 } 662 huksOptions.properties[0].value = alg; 663 huksOptions.properties[3].value = keyType; 664 665 // Compare the key types. 666 if (huksOptions.properties[3].value === huks.HuksImportKeyType.HUKS_KEY_TYPE_KEY_PAIR) { 667 /* Concatenate the huksOptions.inData field with a non-public key in the following format: 668 * keyAlg type (4 bytes) + key_x25519 length (4 bytes) + 669 * g_x25519PubData length (4) + g_x25519PriData length (4) + 670 * Reserved size (4 bytes) + g_x25519PubData + 671 * g_x25519PriData 672 */ 673 // Key pair 674 let Material = new Uint32Array([huks.HuksKeyAlg.HUKS_ALG_X25519, huks.HuksKeySize.HUKS_CURVE25519_KEY_SIZE_256, g_x25519PriData.length, g_x25519PubData.length, 0]); 675 let u8Material = Uint32ToUint8(Material); 676 let strMaterial = Uint8ArrayToString(u8Material); 677 let strXData = strMaterial.concat(Uint8ArrayToString(g_x25519PubData)); 678 let strData = strXData.concat(Uint8ArrayToString(g_x25519PriData)); 679 huksOptions.inData = StringToUint8Array(strData); 680 } else if (huksOptions.properties[3].value === huks.HuksImportKeyType.HUKS_KEY_TYPE_PRIVATE_KEY) { 681 // Private key 682 huksOptions.inData = g_x25519PriData; 683 } else if (huksOptions.properties[3].value === huks.HuksImportKeyType.HUKS_KEY_TYPE_PUBLIC_KEY) { 684 // Public key 685 huksOptions.inData = g_x25519PubData; 686 } 687 await publicImportKeyFunc(importKeyAlias, huksOptions); 688 await publicDeleteKeyFunc(importKeyAlias, huksOptions); 689} 690 691@Entry 692@Component 693struct Index { 694 build() { 695 Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { 696 Button() { 697 Text('testExportRsa') 698 .fontSize(30) 699 .fontWeight(FontWeight.Bold) 700 }.type(ButtonType.Capsule) 701 .margin({ 702 top: 20 703 }) 704 .backgroundColor('#0D9FFB') 705 .onClick(() => { 706 testExportRsa(); 707 }) 708 709 Button() { 710 Text('testImportDh') 711 .fontSize(30) 712 .fontWeight(FontWeight.Bold) 713 }.type(ButtonType.Capsule) 714 .margin({ 715 top: 20 716 }) 717 .backgroundColor('#0D9FFB') 718 .onClick(() => { 719 ImportDhTest(huks.HuksKeyAlg.HUKS_ALG_DH, huks.HuksImportKeyType.HUKS_KEY_TYPE_PRIVATE_KEY); 720 }) 721 722 Button() { 723 Text('testImportRsa') 724 .fontSize(30) 725 .fontWeight(FontWeight.Bold) 726 }.type(ButtonType.Capsule) 727 .margin({ 728 top: 20 729 }) 730 .backgroundColor('#0D9FFB') 731 .onClick(() => { 732 ImportRsaTest(huks.HuksKeyAlg.HUKS_ALG_RSA, huks.HuksImportKeyType.HUKS_KEY_TYPE_KEY_PAIR); 733 }) 734 735 Button() { 736 Text('testImportX25519') 737 .fontSize(30) 738 .fontWeight(FontWeight.Bold) 739 }.type(ButtonType.Capsule) 740 .margin({ 741 top: 20 742 }) 743 .backgroundColor('#0D9FFB') 744 .onClick(() => { 745 ImportX25519Test(huks.HuksKeyAlg.HUKS_ALG_X25519, huks.HuksImportKeyType.HUKS_KEY_TYPE_PRIVATE_KEY); 746 }) 747 748 Button() { 749 Text('testImportEcc') 750 .fontSize(30) 751 .fontWeight(FontWeight.Bold) 752 }.type(ButtonType.Capsule) 753 .margin({ 754 top: 20 755 }) 756 .backgroundColor('#0D9FFB') 757 .onClick(() => { 758 ImportEccTest(huks.HuksKeyAlg.HUKS_ALG_ECC, huks.HuksImportKeyType.HUKS_KEY_TYPE_PUBLIC_KEY); 759 }) 760 } 761 .width('100%') 762 .height('100%') 763 } 764} 765``` 766 767### Secure Key Import 768 769The service invoker and HUKS negotiate a shared symmetric key to encrypt and decrypt the intermediate key and the key to be imported. After the encrypted key is imported, it is decrypted and saved in HUKS. The keys in plaintext can be processed in HUKS only. 770 771The development procedure is as follows: 772 7731. Generate a key pair in HUKS. The key pair is used to encrypt the key to import. 7742. Export the public key of the key pair and obtain a shared secret through key agreement. 7753. Generate intermediate key materials to encrypt the key. 7764. Import the key. 777 778**Supported Key Types** 779 780AES128, AES192, AES256, RSA512, RSA768, RSA1024, RSA2048, RSA3072, RSA4096, HmacSHA1, HmacSHA224, HmacSHA256, HmacSHA384, HmacSHA512, ECC224, ECC256, ECC384, ECC521, Curve25519, DSA, SM2, SM3, SM4 781 782> **NOTICE** 783> 784> - When generating a public key, set **HUKS_TAG_PURPOSE = HUKS_KEY_PURPOSE_UNWRAP**. 785> - Set **HUKS_TAG_IMPORT_KEY_TYPE = HUKS_KEY_TYPE_KEY_PAIR**. 786> - When importing a key in secure mode, add **HUKS_TAG_UNWRAP_ALGORITHM_SUITE** with value set to **HUKS_UNWRAP_SUITE_X25519_AES_256_GCM_NOPADDING** or **HUKS_UNWRAP_SUITE_ECDH_AES_256_GCM_NOPADDING**. 787> - The key alias cannot exceed 64 bytes. 788 789Before you get started, understand the following variables: 790 791| Parameter | Type | Mandatory| Description | 792| -------------- | ----------- | ---- | -------------------------------- | 793| importAlias | string | Yes | Alias of the key to import. | 794| wrapAlias | string | Yes | Alias of the key. | 795| genWrapOptions | HuksOptions | Yes | Tags required for generating the key.| 796| importOptions | HuksOptions | Yes | Tags required for importing the encrypted key. | 797 798For details about the APIs, see [HUKS](../reference/apis/js-apis-huks.md). 799 800**Example** 801 802```ts 803import huks from '@ohos.security.huks'; 804 805async function publicExportKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) { 806 console.info(`enter callback export`); 807 try { 808 await exportKeyItem(keyAlias, huksOptions) 809 .then ((data) => { 810 console.info(`callback: exportKeyItem success, data = ${JSON.stringify(data)}`); 811 if (data.outData !== null) { 812 exportKey = data.outData; 813 } 814 }) 815 .catch(error => { 816 console.error(`callback: exportKeyItem failed, code: ${error.code}, msg: ${error.message}`); 817 }); 818 } catch (error) { 819 console.error(`callback: exportKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`); 820 } 821} 822 823function exportKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) : Promise<huks.HuksReturnResult> { 824 return new Promise((resolve, reject) => { 825 try { 826 huks.exportKeyItem(keyAlias, huksOptions, function (error, data) { 827 if (error) { 828 reject(error); 829 } else { 830 resolve(data); 831 } 832 }); 833 } catch (error) { 834 throw(error); 835 } 836 }); 837} 838 839async function publicImportKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) { 840 console.info(`enter promise importKeyItem`); 841 try { 842 await importKeyItem(keyAlias, huksOptions) 843 .then ((data) => { 844 console.info(`callback: importKeyItem success, data = ${JSON.stringify(data)}`); 845 }) 846 .catch(error => { 847 console.error(`callback: importKeyItem failed, code: ${error.code}, msg: ${error.message}`); 848 }); 849 } catch (error) { 850 console.error(`callback: importKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`); 851 } 852} 853 854function importKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) { 855 return new Promise((resolve, reject) => { 856 try { 857 huks.importKeyItem(keyAlias, huksOptions, function (error, data) { 858 if (error) { 859 reject(error); 860 } else { 861 resolve(data); 862 } 863 }); 864 } catch (error) { 865 throw(error); 866 } 867 }); 868} 869 870async function publicImportWrappedKey(keyAlias:string, wrappingKeyAlias:string, huksOptions:huks.HuksOptions) { 871 console.info(`enter callback importWrappedKeyItem`); 872 try { 873 await importWrappedKeyItem(keyAlias, wrappingKeyAlias, huksOptions) 874 .then ((data) => { 875 console.info(`callback: importWrappedKeyItem success, data = ${JSON.stringify(data)}`); 876 }) 877 .catch(error => { 878 console.error(`callback: importWrappedKeyItem failed, code: ${error.code}, msg: ${error.message}`); 879 }); 880 } catch (error) { 881 console.error(`callback: importWrappedKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`); 882 } 883} 884 885function importWrappedKeyItem(keyAlias:string, wrappingKeyAlias:string, huksOptions:huks.HuksOptions) { 886 return new Promise((resolve, reject) => { 887 try { 888 huks.importWrappedKeyItem(keyAlias, wrappingKeyAlias, huksOptions, function (error, data) { 889 if (error) { 890 reject(error); 891 } else { 892 resolve(data); 893 } 894 }); 895 } catch (error) { 896 throw(error); 897 } 898 }); 899} 900 901async function publicDeleteKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) { 902 console.info(`enter callback deleteKeyItem`); 903 try { 904 await deleteKeyItem(keyAlias, huksOptions) 905 .then ((data) => { 906 console.info(`callback: deleteKeyItem key success, data = ${JSON.stringify(data)}`); 907 }) 908 .catch(error => { 909 console.error(`callback: deleteKeyItem failed, code: ${error.code}, msg: ${error.message}`); 910 }); 911 } catch (error) { 912 console.error(`callback: deleteKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`); 913 } 914} 915 916function deleteKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) { 917 return new Promise((resolve, reject) => { 918 try { 919 huks.deleteKeyItem(keyAlias, huksOptions, function (error, data) { 920 if (error) { 921 reject(error); 922 } else { 923 resolve(data); 924 } 925 }); 926 } catch (error) { 927 throw(error); 928 } 929 }); 930} 931 932let importAlias = "importAlias"; 933let wrapAlias = "wrappingKeyAlias"; 934let exportKey; 935 936let inputEccPair = new Uint8Array([ 937 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 938 0x20, 0x00, 0x00, 0x00, 0xa5, 0xb8, 0xa3, 0x78, 0x1d, 0x6d, 0x76, 0xe0, 0xb3, 0xf5, 0x6f, 0x43, 939 0x9d, 0xcf, 0x60, 0xf6, 0x0b, 0x3f, 0x64, 0x45, 0xa8, 0x3f, 0x1a, 0x96, 0xf1, 0xa1, 0xa4, 0x5d, 940 0x3e, 0x2c, 0x3f, 0x13, 0xd7, 0x81, 0xf7, 0x2a, 0xb5, 0x8d, 0x19, 0x3d, 0x9b, 0x96, 0xc7, 0x6a, 941 0x10, 0xf0, 0xaa, 0xbc, 0x91, 0x6f, 0x4d, 0xa7, 0x09, 0xb3, 0x57, 0x88, 0x19, 0x6f, 0x00, 0x4b, 942 0xad, 0xee, 0x34, 0x35, 0xfb, 0x8b, 0x9f, 0x12, 0xa0, 0x83, 0x19, 0xbe, 0x6a, 0x6f, 0x63, 0x2a, 943 0x7c, 0x86, 0xba, 0xca, 0x64, 0x0b, 0x88, 0x96, 0xe2, 0xfa, 0x77, 0xbc, 0x71, 0xe3, 0x0f, 0x0f, 944 0x9e, 0x3c, 0xe5, 0xf9]); 945 946let properties = new Array(); 947properties[0] = { 948 tag: huks.HuksTag.HUKS_TAG_ALGORITHM, 949 value: huks.HuksKeyAlg.HUKS_ALG_ECC 950}; 951properties[1] = { 952 tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, 953 value: huks.HuksKeySize.HUKS_ECC_KEY_SIZE_256 954}; 955properties[2] = { 956 tag: huks.HuksTag.HUKS_TAG_PURPOSE, 957 value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_UNWRAP 958}; 959properties[3] = { 960 tag: huks.HuksTag.HUKS_TAG_DIGEST, 961 value: huks.HuksKeyDigest.HUKS_DIGEST_SHA256 962}; 963properties[4] = { 964 tag: huks.HuksTag.HUKS_TAG_IMPORT_KEY_TYPE, 965 value: huks.HuksImportKeyType.HUKS_KEY_TYPE_KEY_PAIR, 966}; 967let huksOptions = { 968 properties: properties, 969 inData: inputEccPair 970}; 971 972let importProperties = new Array(); 973importProperties[0] = { 974 tag: huks.HuksTag.HUKS_TAG_ALGORITHM, 975 value: huks.HuksKeyAlg.HUKS_ALG_AES 976}; 977importProperties[1] = { 978 tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, 979 value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_256 980}; 981importProperties[2] = { 982 tag: huks.HuksTag.HUKS_TAG_PURPOSE, 983 value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT | huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT 984}; 985importProperties[3] = { 986 tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE, 987 value: huks.HuksCipherMode.HUKS_MODE_CBC 988}; 989importProperties[4] = { 990 tag: huks.HuksTag.HUKS_TAG_PADDING, 991 value: huks.HuksKeyPadding.HUKS_PADDING_NONE 992}; 993importProperties[5] = { 994 tag: huks.HuksTag.HUKS_TAG_UNWRAP_ALGORITHM_SUITE, 995 value: huks.HuksUnwrapSuite.HUKS_UNWRAP_SUITE_ECDH_AES_256_GCM_NOPADDING 996}; 997let importOptions = { 998 properties: importProperties, 999 inData: new Uint8Array(new Array()) 1000}; 1001 1002async function importWrappedKeyItemTest() { 1003 1004 console.info(`enter ImportWrapKey test`); 1005 await publicImportKeyFunc(wrapAlias, huksOptions); 1006 1007 await publicExportKeyFunc(wrapAlias, huksOptions); 1008 1009 /* The following operation does not involve calling of HUKS APIs, and the specific implementation is not provided here. 1010 * For example, import keyA. 1011 * 1. Use ECC to generate a public and private key pair named keyB. The public key is keyB_pub, and the private key is keyB_pri. 1012 * 2. Use keyB_pri and the public key obtained from wrappingAlias to negotiate the shared key share_key. 1013 * 3. Randomly generate a key kek to encrypt keyA using AES-GCM. During the encryption, record nonce1, aad1, ciphertext keyA_enc, and encrypted tag1. 1014 * 4. Use share_key to encrypt kek using AES-GCM. During the encryption, record nonce2, aad2, ciphertext kek_enc, and encrypted tag2. 1015 * 5. Generate the **importOptions.inData** field in the following format: 1016 * keyB_pub length (4 bytes) + keyB_pub + aad2 length (4 bytes) + aad2 + 1017 * nonce2 length (4 bytes) + nonce2 + tag2 length (4 bytes) + tag2 + 1018 * kek_enc length (4 bytes) + kek_enc + aad1 length (4 bytes) + aad1 + 1019 * nonce1 length (4 bytes) + nonce1 + tag1 length (4 bytes) + tag1 + 1020 * Memory occupied by the keyA length (4 bytes) + keyA length + keyA_enc length (4 bytes) + keyA_enc 1021 */ 1022 let inputKey = new Uint8Array([ 1023 0x5b, 0x00, 0x00, 0x00, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 1024 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0xc0, 1025 0xfe, 0x1c, 0x67, 0xde, 0x86, 0x0e, 0xfb, 0xaf, 0xb5, 0x85, 0x52, 0xb4, 0x0e, 0x1f, 0x6c, 0x6c, 1026 0xaa, 0xc5, 0xd9, 0xd2, 0x4d, 0xb0, 0x8a, 0x72, 0x24, 0xa1, 0x99, 0xaf, 0xfc, 0x3e, 0x55, 0x5a, 1027 0xac, 0x99, 0x3d, 0xe8, 0x34, 0x72, 0xb9, 0x47, 0x9c, 0xa6, 0xd8, 0xfb, 0x00, 0xa0, 0x1f, 0x9f, 1028 0x7a, 0x41, 0xe5, 0x44, 0x3e, 0xb2, 0x76, 0x08, 0xa2, 0xbd, 0xe9, 0x41, 0xd5, 0x2b, 0x9e, 0x10, 1029 0x00, 0x00, 0x00, 0xbf, 0xf9, 0x69, 0x41, 0xf5, 0x49, 0x85, 0x31, 0x35, 0x14, 0x69, 0x12, 0x57, 1030 0x9c, 0xc8, 0xb7, 0x10, 0x00, 0x00, 0x00, 0x2d, 0xb7, 0xf1, 0x5a, 0x0f, 0xb8, 0x20, 0xc5, 0x90, 1031 0xe5, 0xca, 0x45, 0x84, 0x5c, 0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x43, 0x25, 0x1b, 0x2f, 0x5b, 1032 0x86, 0xd8, 0x87, 0x04, 0x4d, 0x38, 0xc2, 0x65, 0xcc, 0x9e, 0xb7, 0x20, 0x00, 0x00, 0x00, 0xf4, 1033 0xe8, 0x93, 0x28, 0x0c, 0xfa, 0x4e, 0x11, 0x6b, 0xe8, 0xbd, 0xa8, 0xe9, 0x3f, 0xa7, 0x8f, 0x2f, 1034 0xe3, 0xb3, 0xbf, 0xaf, 0xce, 0xe5, 0x06, 0x2d, 0xe6, 0x45, 0x5d, 0x19, 0x26, 0x09, 0xe7, 0x10, 1035 0x00, 0x00, 0x00, 0xf4, 0x1e, 0x7b, 0x01, 0x7a, 0x84, 0x36, 0xa4, 0xa8, 0x1c, 0x0d, 0x3d, 0xde, 1036 0x57, 0x66, 0x73, 0x10, 0x00, 0x00, 0x00, 0xe3, 0xff, 0x29, 0x97, 0xad, 0xb3, 0x4a, 0x2c, 0x50, 1037 0x08, 0xb5, 0x68, 0xe1, 0x90, 0x5a, 0xdc, 0x10, 0x00, 0x00, 0x00, 0x26, 0xae, 0xdc, 0x4e, 0xa5, 1038 0x6e, 0xb1, 0x38, 0x14, 0x24, 0x47, 0x1c, 0x41, 0x89, 0x63, 0x11, 0x04, 0x00, 0x00, 0x00, 0x20, 1039 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0b, 0xcb, 0xa9, 0xa8, 0x5f, 0x5a, 0x9d, 0xbf, 0xa1, 1040 0xfc, 0x72, 0x74, 0x87, 0x79, 0xf2, 0xf4, 0x22, 0x0c, 0x8a, 0x4d, 0xd8, 0x7e, 0x10, 0xc8, 0x44, 1041 0x17, 0x95, 0xab, 0x3b, 0xd2, 0x8f, 0x0a 1042 ]); 1043 1044 importOptions.inData = inputKey; 1045 await publicImportWrappedKey(importAlias, wrapAlias, importOptions); 1046 1047 await publicDeleteKeyFunc(wrapAlias, huksOptions); 1048 await publicDeleteKeyFunc(importAlias, importOptions); 1049} 1050 1051@Entry 1052@Component 1053struct Index { 1054 build() { 1055 Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { 1056 Button() { 1057 Text('importWrappedKeyItemTest') 1058 .fontSize(30) 1059 .fontWeight(FontWeight.Bold) 1060 }.type(ButtonType.Capsule) 1061 .margin({ 1062 top: 20 1063 }) 1064 .backgroundColor('#0D9FFB') 1065 .onClick(()=>{ 1066 importWrappedKeyItemTest(); 1067 }) 1068 } 1069 .width('100%') 1070 .height('100%') 1071 } 1072} 1073``` 1074 1075### Key Encryption and Decryption 1076 1077Use the symmetric or asymmetric key stored in HUKS to encrypt or decrypt data based on the specified alias. The keys in plaintext must be in a secure environment during the encryption and decryption process. 1078 1079The development procedure is as follows: 1080 10811. Generate a key. 10822. Encrypt the key. 10833. Decrypt the key. 1084 1085**Supported key types**: 1086 1087| HUKS_ALG_ALGORITHM | HUKS_TAG_PURPOSE | HUKS_TAG_DIGEST | HUKS_TAG_PADDING | HUKS_TAG_BLOCK_MODE | HUKS_TAG_IV | 1088| ------------------------------------------------------------ | -------------------------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------- | ----------- | 1089| HUKS_ALG_SM4 (supported key length: HUKS_SM4_KEY_SIZE_128)| HUKS_KEY_PURPOSE_ENCRYPT or HUKS_KEY_PURPOSE_DECRYPT| Optional | HUKS_PADDING_NONE | HUKS_MODE_CTR HUKS_MODE_ECB HUKS_MODE_CBC | Mandatory | 1090| HUKS_ALG_SM4 (supported key length: HUKS_SM4_KEY_SIZE_128)| HUKS_KEY_PURPOSE_ENCRYPT or HUKS_KEY_PURPOSE_DECRYPT| Optional | HUKS_PADDING_PKCS7 | HUKS_MODE_ECB HUKS_MODE_CBC | Mandatory | 1091| HUKS_ALG_RSA (supported lengths: HUKS_RSA_KEY_SIZE_512, HUKS_RSA_KEY_SIZE_768, HUKS_RSA_KEY_SIZE_1024, HUKS_RSA_KEY_SIZE_2048, HUKS_RSA_KEY_SIZE_3072, HUKS_RSA_KEY_SIZE_4096)| HUKS_KEY_PURPOSE_ENCRYPT or HUKS_KEY_PURPOSE_DECRYPT| HUKS_DIGEST_SHA1 HUKS_DIGEST_SHA224 HUKS_DIGEST_SHA256 HUKS_DIGEST_SHA384 HUKS_DIGEST_SHA512 | HUKS_PADDING_NONE HUKS_PADDING_PKCS1_V1_5 HUKS_PADDING_OAEP | HUKS_MODE_ECB | Optional | 1092 1093| HUKS_ALG_ALGORITHM | HUKS_TAG_PURPOSE | HUKS_TAG_PADDING | HUKS_TAG_BLOCK_MODE | HUKS_TAG_IV | HUKS_TAG_NONCE | HUKS_TAG_ASSOCIATED_DATA | HUKS_TAG_AE_TAG | 1094| ------------------------------------------------------------ | ------------------------ | ------------------------------------- | ---------------------------- | ----------- | -------------- | ------------------------ | --------------- | 1095| HUKS_ALG_AES (supported key lengths: HUKS_AES_KEY_SIZE_128, HUKS_AES_KEY_SIZE_192, HUKS_AES_KEY_SIZE_256)| HUKS_KEY_PURPOSE_ENCRYPT | HUKS_PADDING_NONE, HUKS_PADDING_PKCS7| HUKS_MODE_CBC | Mandatory | Optional | Optional | Optional | 1096| HUKS_ALG_AES | HUKS_KEY_PURPOSE_ENCRYPT | HUKS_PADDING_NONE | HUKS_MODE_CCM HUKS_MODE_GCM | Optional | Mandatory | Mandatory | Optional | 1097| HUKS_ALG_AES | HUKS_KEY_PURPOSE_ENCRYPT | HUKS_PADDING_NONE | HUKS_MODE_CTR | Mandatory | Optional | Optional | Optional | 1098| HUKS_ALG_AES | HUKS_KEY_PURPOSE_ENCRYPT | HUKS_PADDING_PKCS7 HUKS_PADDING_NONE | HUKS_MODE_ECB | Mandatory | Optional | Optional | Optional | 1099| HUKS_ALG_AES | HUKS_KEY_PURPOSE_DECRYPT | HUKS_PADDING_NONE, HUKS_PADDING_PKCS7| HUKS_MODE_CBC | Mandatory | Optional | Optional | Mandatory | 1100| HUKS_ALG_AES | HUKS_KEY_PURPOSE_DECRYPT | HUKS_PADDING_NONE | HUKS_MODE_CCM HUKS_MODE_GCM | Optional | Mandatory | Mandatory | Optional | 1101| HUKS_ALG_AES | HUKS_KEY_PURPOSE_DECRYPT | HUKS_PADDING_NONE | HUKS_MODE_CTR | Mandatory | Optional | Optional | Optional | 1102| HUKS_ALG_AES | HUKS_KEY_PURPOSE_DECRYPT | HUKS_PADDING_NONE, HUKS_PADDING_PKCS7| HUKS_MODE_ECB | Mandatory | Optional | Optional | Optional | 1103 1104> **NOTE**<br> 1105> 1106> The key alias cannot exceed 64 bytes. 1107 1108Before you get started, understand the following variables: 1109 1110| Parameter | Type | Mandatory| Description | 1111| -------------- | ----------- | ---- | ------------------------ | 1112| srcKeyAlias | string | Yes | Alias of the key. | 1113| huksOptions | HuksOptions | Yes | Tags required for generating the key.| 1114| encryptOptions | HuksOptions | Yes | Tags required for encrypting the key.| 1115| decryptOptions | HuksOptions | Yes | Tags required for decrypting the key.| 1116 1117For details about the APIs, see [HUKS](../reference/apis/js-apis-huks.md). 1118 1119**Example 1:** 1120 1121```ts 1122/* The cipher operation supports RSA, AES, and SM4 keys. 1123 * 1124 * The following uses the Promise() operation of an SM4 128-bit key as an example. 1125 */ 1126import huks from '@ohos.security.huks'; 1127 1128function StringToUint8Array(str) { 1129 let arr = []; 1130 for (let i = 0, j = str.length; i < j; ++i) { 1131 arr.push(str.charCodeAt(i)); 1132 } 1133 return new Uint8Array(arr); 1134} 1135 1136function Uint8ArrayToString(fileData) { 1137 let dataString = ''; 1138 for (let i = 0; i < fileData.length; i++) { 1139 dataString += String.fromCharCode(fileData[i]); 1140 } 1141 return dataString; 1142} 1143 1144async function publicGenKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) { 1145 console.info(`enter callback generateKeyItem`); 1146 try { 1147 await generateKeyItem(keyAlias, huksOptions) 1148 .then((data) => { 1149 console.info(`callback: generateKeyItem success, data = ${JSON.stringify(data)}`); 1150 }) 1151 .catch(error => { 1152 console.error(`callback: generateKeyItem failed, code: ${error.code}, msg: ${error.message}`); 1153 }); 1154 } catch (error) { 1155 console.error(`callback: generateKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`); 1156 } 1157} 1158 1159function generateKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) { 1160 return new Promise((resolve, reject) => { 1161 try { 1162 huks.generateKeyItem(keyAlias, huksOptions, function (error, data) { 1163 if (error) { 1164 reject(error); 1165 } else { 1166 resolve(data); 1167 } 1168 }); 1169 } catch (error) { 1170 throw(error); 1171 } 1172 }); 1173} 1174 1175async function publicInitFunc(keyAlias:string, huksOptions:huks.HuksOptions) { 1176 console.info(`enter promise doInit`); 1177 try { 1178 await huks.initSession(keyAlias, huksOptions) 1179 .then ((data) => { 1180 console.info(`promise: doInit success, data = ${JSON.stringify(data)}`); 1181 handle = data.handle; 1182 }) 1183 .catch(error => { 1184 console.error(`promise: doInit key failed, code: ${error.code}, msg: ${error.message}`); 1185 }); 1186 } catch (error) { 1187 console.error(`promise: doInit input arg invalid, code: ${error.code}, msg: ${error.message}`); 1188 } 1189} 1190 1191async function publicUpdateFunc(handle:number, huksOptions:huks.HuksOptions) { 1192 console.info(`enter callback doUpdate`); 1193 try { 1194 await updateSession(handle, huksOptions) 1195 .then ((data) => { 1196 console.info(`callback: doUpdate success, data = ${JSON.stringify(data)}`); 1197 updateResult = Array.from(data.outData); 1198 }) 1199 .catch(error => { 1200 console.error(`callback: doUpdate failed, code: ${error.code}, msg: ${error.message}`); 1201 }); 1202 } catch (error) { 1203 console.error(`callback: doUpdate input arg invalid, code: ${error.code}, msg: ${error.message}`); 1204 } 1205} 1206 1207function updateSession(handle:number, huksOptions:huks.HuksOptions) : Promise<huks.HuksReturnResult> { 1208 return new Promise((resolve, reject) => { 1209 try { 1210 huks.updateSession(handle, huksOptions, function (error, data) { 1211 if (error) { 1212 reject(error); 1213 } else { 1214 resolve(data); 1215 } 1216 }); 1217 } catch (error) { 1218 throw(error); 1219 } 1220 }); 1221} 1222 1223async function publicFinishFunc(handle:number, huksOptions:huks.HuksOptions) { 1224 console.info(`enter callback doFinish`); 1225 try { 1226 await finishSession(handle, huksOptions) 1227 .then ((data) => { 1228 finishOutData = Uint8ArrayToString(new Uint8Array(updateResult)); 1229 console.info(`callback: doFinish success, data = ${JSON.stringify(data)}`); 1230 }) 1231 .catch(error => { 1232 console.error(`callback: doFinish failed, code: ${error.code}, msg: ${error.message}`); 1233 }); 1234 } catch (error) { 1235 console.error(`callback: doFinish input arg invalid, code: ${error.code}, msg: ${error.message}`); 1236 } 1237} 1238 1239function finishSession(handle:number, huksOptions:huks.HuksOptions) : Promise<huks.HuksReturnResult> { 1240 return new Promise((resolve, reject) => { 1241 try { 1242 huks.finishSession(handle, huksOptions, function (error, data) { 1243 if (error) { 1244 reject(error); 1245 } else { 1246 resolve(data); 1247 } 1248 }); 1249 } catch (error) { 1250 throw(error); 1251 } 1252 }); 1253} 1254 1255async function publicDeleteKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) { 1256 console.info(`enter callback deleteKeyItem`); 1257 try { 1258 await deleteKeyItem(keyAlias, huksOptions) 1259 .then ((data) => { 1260 console.info(`callback: deleteKeyItem key success, data = ${JSON.stringify(data)}`); 1261 }) 1262 .catch(error => { 1263 console.error(`callback: deleteKeyItem failed, code: ${error.code}, msg: ${error.message}`); 1264 }); 1265 } catch (error) { 1266 console.error(`callback: deleteKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`); 1267 } 1268} 1269 1270function deleteKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) { 1271 return new Promise((resolve, reject) => { 1272 try { 1273 huks.deleteKeyItem(keyAlias, huksOptions, function (error, data) { 1274 if (error) { 1275 reject(error); 1276 } else { 1277 resolve(data); 1278 } 1279 }); 1280 } catch (error) { 1281 throw(error); 1282 } 1283 }); 1284} 1285 1286let IV = '0000000000000000'; 1287let cipherInData = 'Hks_SM4_Cipher_Test_101010101010101010110_string'; 1288let srcKeyAlias = 'huksCipherSm4SrcKeyAlias'; 1289let encryptUpdateResult = new Array(); 1290let handle; 1291let updateResult = new Array(); 1292let finishOutData; 1293 1294async function testSm4Cipher() { 1295 /* Integrate the key generation parameter set and key encryption parameter set. */ 1296 let properties = new Array(); 1297 properties[0] = { 1298 tag: huks.HuksTag.HUKS_TAG_ALGORITHM, 1299 value: huks.HuksKeyAlg.HUKS_ALG_SM4, 1300 } 1301 properties[1] = { 1302 tag: huks.HuksTag.HUKS_TAG_PURPOSE, 1303 value: 1304 huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT | 1305 huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT, 1306 } 1307 properties[2] = { 1308 tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, 1309 value: huks.HuksKeySize.HUKS_SM4_KEY_SIZE_128, 1310 } 1311 properties[3] = { 1312 tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE, 1313 value: huks.HuksCipherMode.HUKS_MODE_CBC, 1314 } 1315 properties[4] = { 1316 tag: huks.HuksTag.HUKS_TAG_PADDING, 1317 value: huks.HuksKeyPadding.HUKS_PADDING_NONE, 1318 } 1319 let huksOptions = { 1320 properties: properties, 1321 inData: new Uint8Array(new Array()) 1322 } 1323 1324 let propertiesEncrypt = new Array(); 1325 propertiesEncrypt[0] = { 1326 tag: huks.HuksTag.HUKS_TAG_ALGORITHM, 1327 value: huks.HuksKeyAlg.HUKS_ALG_SM4, 1328 } 1329 propertiesEncrypt[1] = { 1330 tag: huks.HuksTag.HUKS_TAG_PURPOSE, 1331 value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT, 1332 } 1333 propertiesEncrypt[2] = { 1334 tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, 1335 value: huks.HuksKeySize.HUKS_SM4_KEY_SIZE_128, 1336 } 1337 propertiesEncrypt[3] = { 1338 tag: huks.HuksTag.HUKS_TAG_PADDING, 1339 value: huks.HuksKeyPadding.HUKS_PADDING_NONE, 1340 } 1341 propertiesEncrypt[4] = { 1342 tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE, 1343 value: huks.HuksCipherMode.HUKS_MODE_CBC, 1344 } 1345 propertiesEncrypt[5] = { 1346 tag: huks.HuksTag.HUKS_TAG_IV, 1347 value: StringToUint8Array(IV), 1348 } 1349 let encryptOptions = { 1350 properties: propertiesEncrypt, 1351 inData: new Uint8Array(new Array()) 1352 } 1353 1354 /* Generate a key. */ 1355 await publicGenKeyFunc(srcKeyAlias, huksOptions); 1356 1357 /* Encrypt the key. */ 1358 await publicInitFunc(srcKeyAlias, encryptOptions); 1359 1360 encryptOptions.inData = StringToUint8Array(cipherInData); 1361 await publicUpdateFunc(handle, encryptOptions); 1362 encryptUpdateResult = updateResult; 1363 1364 encryptOptions.inData = new Uint8Array(new Array()); 1365 await publicFinishFunc(handle, encryptOptions); 1366 if (finishOutData === cipherInData) { 1367 console.info('test finish encrypt err '); 1368 } else { 1369 console.info('test finish encrypt success'); 1370 } 1371 1372 /* Modify the key encryption parameter set to the decryption parameter set. */ 1373 propertiesEncrypt.splice(1, 1, { 1374 tag: huks.HuksTag.HUKS_TAG_PURPOSE, 1375 value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT, 1376 }); 1377 let decryptOptions = { 1378 properties: propertiesEncrypt, 1379 inData: new Uint8Array(new Array()) 1380 } 1381 1382 /* Decrypt the key. */ 1383 await publicInitFunc(srcKeyAlias, decryptOptions); 1384 1385 decryptOptions.inData = new Uint8Array(encryptUpdateResult); 1386 await publicUpdateFunc(handle, decryptOptions); 1387 1388 decryptOptions.inData = new Uint8Array(new Array()); 1389 await publicFinishFunc(handle, decryptOptions); 1390 if (finishOutData === cipherInData) { 1391 console.info('test finish decrypt success '); 1392 } else { 1393 console.info('test finish decrypt err'); 1394 } 1395 1396 await publicDeleteKeyFunc(srcKeyAlias, huksOptions); 1397} 1398 1399@Entry 1400@Component 1401struct Index { 1402 build() { 1403 Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { 1404 Button() { 1405 Text('testSm4Cipher') 1406 .fontSize(30) 1407 .fontWeight(FontWeight.Bold) 1408 }.type(ButtonType.Capsule) 1409 .margin({ 1410 top: 20 1411 }) 1412 .backgroundColor('#0D9FFB') 1413 .onClick(()=>{ 1414 testSm4Cipher(); 1415 }) 1416 } 1417 .width('100%') 1418 .height('100%') 1419 } 1420} 1421``` 1422 1423**Example 2:** 1424 1425```ts 1426/* The cipher operation supports RSA, AES, and SM4 keys. 1427 * 1428 * The following uses the Promise() operation of an AES128 GCM key as an example. 1429 */ 1430import huks from '@ohos.security.huks'; 1431 1432function StringToUint8Array(str) { 1433 let arr = []; 1434 for (let i = 0, j = str.length; i < j; ++i) { 1435 arr.push(str.charCodeAt(i)); 1436 } 1437 return new Uint8Array(arr); 1438} 1439 1440function Uint8ArrayToString(fileData) { 1441 let dataString = ''; 1442 for (let i = 0; i < fileData.length; i++) { 1443 dataString += String.fromCharCode(fileData[i]); 1444 } 1445 return dataString; 1446} 1447 1448async function publicGenKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) { 1449 console.info(`enter callback generateKeyItem`); 1450 try { 1451 await generateKeyItem(keyAlias, huksOptions) 1452 .then((data) => { 1453 console.info(`callback: generateKeyItem success, data = ${JSON.stringify(data)}`); 1454 }) 1455 .catch(error => { 1456 console.error(`callback: generateKeyItem failed, code: ${error.code}, msg: ${error.message}`); 1457 }); 1458 } catch (error) { 1459 console.error(`callback: generateKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`); 1460 } 1461} 1462 1463function generateKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) { 1464 return new Promise((resolve, reject) => { 1465 try { 1466 huks.generateKeyItem(keyAlias, huksOptions, function (error, data) { 1467 if (error) { 1468 reject(error); 1469 } else { 1470 resolve(data); 1471 } 1472 }); 1473 } catch (error) { 1474 throw(error); 1475 } 1476 }); 1477} 1478 1479async function publicInitFunc(keyAlias:string, huksOptions:huks.HuksOptions) { 1480 console.info(`enter promise doInit`); 1481 try { 1482 await huks.initSession(keyAlias, huksOptions) 1483 .then ((data) => { 1484 console.info(`promise: doInit success, data = ${JSON.stringify(data)}`); 1485 handle = data.handle; 1486 }) 1487 .catch(error => { 1488 console.error(`promise: doInit key failed, code: ${error.code}, msg: ${error.message}`); 1489 }); 1490 } catch (error) { 1491 console.error(`promise: doInit input arg invalid, code: ${error.code}, msg: ${error.message}`); 1492 } 1493} 1494 1495async function publicUpdateFunc(handle:number, huksOptions:huks.HuksOptions) { 1496 console.info(`enter callback doUpdate`); 1497 try { 1498 await updateSession(handle, huksOptions) 1499 .then ((data) => { 1500 console.info(`callback: doUpdate success, data = ${JSON.stringify(data)}`); 1501 updateResult = Array.from(data.outData); 1502 }) 1503 .catch(error => { 1504 console.error(`callback: doUpdate failed, code: ${error.code}, msg: ${error.message}`); 1505 }); 1506 } catch (error) { 1507 console.error(`callback: doUpdate input arg invalid, code: ${error.code}, msg: ${error.message}`); 1508 } 1509} 1510 1511function updateSession(handle:number, huksOptions:huks.HuksOptions) : Promise<huks.HuksReturnResult> { 1512 return new Promise((resolve, reject) => { 1513 try { 1514 huks.updateSession(handle, huksOptions, function (error, data) { 1515 if (error) { 1516 reject(error); 1517 } else { 1518 resolve(data); 1519 } 1520 }); 1521 } catch (error) { 1522 throw(error); 1523 } 1524 }); 1525} 1526 1527async function publicFinishFunc(handle:number, huksOptions:huks.HuksOptions) { 1528 console.info(`enter callback doFinish`); 1529 try { 1530 await finishSession(handle, huksOptions) 1531 .then ((data) => { 1532 updateResult = updateResult.concat(Array.from(data.outData)); 1533 console.info(`callback: doFinish success, data = ${JSON.stringify(data)}`); 1534 }) 1535 .catch(error => { 1536 console.error(`callback: doFinish failed, code: ${error.code}, msg: ${error.message}`); 1537 }); 1538 } catch (error) { 1539 console.error(`callback: doFinish input arg invalid, code: ${error.code}, msg: ${error.message}`); 1540 } 1541} 1542 1543function finishSession(handle:number, huksOptions:huks.HuksOptions) : Promise<huks.HuksReturnResult> { 1544 return new Promise((resolve, reject) => { 1545 try { 1546 huks.finishSession(handle, huksOptions, function (error, data) { 1547 if (error) { 1548 reject(error); 1549 } else { 1550 resolve(data); 1551 } 1552 }); 1553 } catch (error) { 1554 throw(error); 1555 } 1556 }); 1557} 1558 1559async function publicDeleteKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) { 1560 console.info(`enter callback deleteKeyItem`); 1561 try { 1562 await deleteKeyItem(keyAlias, huksOptions) 1563 .then ((data) => { 1564 console.info(`callback: deleteKeyItem key success, data = ${JSON.stringify(data)}`); 1565 }) 1566 .catch(error => { 1567 console.error(`callback: deleteKeyItem failed, code: ${error.code}, msg: ${error.message}`); 1568 }); 1569 } catch (error) { 1570 console.error(`callback: deleteKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`); 1571 } 1572} 1573 1574function deleteKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) { 1575 return new Promise((resolve, reject) => { 1576 try { 1577 huks.deleteKeyItem(keyAlias, huksOptions, function (error, data) { 1578 if (error) { 1579 reject(error); 1580 } else { 1581 resolve(data); 1582 } 1583 }); 1584 } catch (error) { 1585 throw(error); 1586 } 1587 }); 1588} 1589 1590let AAD = '0000000000000000'; 1591let NONCE = '000000000000'; 1592let AEAD = '0000000000000000'; 1593let cipherInData = 'Hks_AES_Cipher_Test_00000000000000000000000000000000000000000000000000000_string'; 1594let srcKeyAlias = 'huksCipherSm4SrcKeyAlias'; 1595let updateResult = new Array(); 1596let encryptUpdateResult = new Array(); 1597let decryptUpdateResult = new Array(); 1598let handle; 1599let finishOutData; 1600 1601async function testAesCipher() { 1602 /* Integrate the key generation parameter set and key encryption parameter set. */ 1603 let properties = new Array(); 1604 properties[0] = { 1605 tag: huks.HuksTag.HUKS_TAG_ALGORITHM, 1606 value: huks.HuksKeyAlg.HUKS_ALG_AES, 1607 } 1608 properties[1] = { 1609 tag: huks.HuksTag.HUKS_TAG_PURPOSE, 1610 value: 1611 huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT | 1612 huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT, 1613 } 1614 properties[2] = { 1615 tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, 1616 value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_128, 1617 } 1618 properties[3] = { 1619 tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE, 1620 value: huks.HuksCipherMode.HUKS_MODE_GCM, 1621 } 1622 properties[4] = { 1623 tag: huks.HuksTag.HUKS_TAG_PADDING, 1624 value: huks.HuksKeyPadding.HUKS_PADDING_NONE, 1625 } 1626 let huksOptions = { 1627 properties: properties, 1628 inData: new Uint8Array(new Array()) 1629 } 1630 1631 let propertiesEncrypt = new Array(); 1632 propertiesEncrypt[0] = { 1633 tag: huks.HuksTag.HUKS_TAG_ALGORITHM, 1634 value: huks.HuksKeyAlg.HUKS_ALG_AES, 1635 } 1636 propertiesEncrypt[1] = { 1637 tag: huks.HuksTag.HUKS_TAG_PURPOSE, 1638 value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT, 1639 } 1640 propertiesEncrypt[2] = { 1641 tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, 1642 value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_128, 1643 } 1644 propertiesEncrypt[3] = { 1645 tag: huks.HuksTag.HUKS_TAG_PADDING, 1646 value: huks.HuksKeyPadding.HUKS_PADDING_NONE, 1647 } 1648 propertiesEncrypt[4] = { 1649 tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE, 1650 value: huks.HuksCipherMode.HUKS_MODE_GCM, 1651 } 1652 propertiesEncrypt[5] = { 1653 tag: huks.HuksTag.HUKS_TAG_DIGEST, 1654 value: huks.HuksKeyDigest.HUKS_DIGEST_NONE, 1655 } 1656 propertiesEncrypt[6] = { 1657 tag: huks.HuksTag.HUKS_TAG_ASSOCIATED_DATA, 1658 value: StringToUint8Array(AAD), 1659 } 1660 propertiesEncrypt[7] = { 1661 tag: huks.HuksTag.HUKS_TAG_NONCE, 1662 value: StringToUint8Array(NONCE), 1663 } 1664 propertiesEncrypt[8] = { 1665 tag: huks.HuksTag.HUKS_TAG_AE_TAG, 1666 value: StringToUint8Array(AEAD), 1667 } 1668 let encryptOptions = { 1669 properties: propertiesEncrypt, 1670 inData: new Uint8Array(new Array()) 1671 } 1672 1673 /* Generate a key. */ 1674 await publicGenKeyFunc(srcKeyAlias, huksOptions); 1675 1676 /* Encrypt the key. */ 1677 await publicInitFunc(srcKeyAlias, encryptOptions); 1678 1679 encryptOptions.inData = StringToUint8Array(cipherInData.slice(0,64)); 1680 await publicUpdateFunc(handle, encryptOptions); 1681 encryptUpdateResult = updateResult; 1682 1683 encryptOptions.inData = StringToUint8Array(cipherInData.slice(64,80)); 1684 await publicFinishFunc(handle, encryptOptions); 1685 encryptUpdateResult = updateResult; 1686 finishOutData = Uint8ArrayToString(new Uint8Array(encryptUpdateResult)); 1687 if (finishOutData === cipherInData) { 1688 console.info('test finish encrypt err '); 1689 } else { 1690 console.info('test finish encrypt success'); 1691 } 1692 1693 /* Modify the key encryption parameter set to the decryption parameter set. */ 1694 propertiesEncrypt.splice(1, 1, { 1695 tag: huks.HuksTag.HUKS_TAG_PURPOSE, 1696 value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT, 1697 }); 1698 propertiesEncrypt.splice(8, 1, { 1699 tag: huks.HuksTag.HUKS_TAG_AE_TAG, 1700 value: new Uint8Array(encryptUpdateResult.splice(encryptUpdateResult.length - 16,encryptUpdateResult.length)) 1701 }); 1702 let decryptOptions = { 1703 properties: propertiesEncrypt, 1704 inData: new Uint8Array(new Array()) 1705 } 1706 1707 /* Decrypt the key. */ 1708 await publicInitFunc(srcKeyAlias, decryptOptions); 1709 1710 decryptOptions.inData = new Uint8Array(encryptUpdateResult.slice(0,64)); 1711 await publicUpdateFunc(handle, decryptOptions); 1712 decryptUpdateResult = updateResult; 1713 1714 decryptOptions.inData = new Uint8Array(encryptUpdateResult.slice(64,encryptUpdateResult.length)); 1715 await publicFinishFunc(handle, decryptOptions); 1716 decryptUpdateResult = updateResult; 1717 finishOutData = Uint8ArrayToString(new Uint8Array(decryptUpdateResult)); 1718 if (finishOutData === cipherInData) { 1719 console.info('test finish decrypt success '); 1720 } else { 1721 console.info('test finish decrypt err'); 1722 } 1723 1724 await publicDeleteKeyFunc(srcKeyAlias, huksOptions); 1725} 1726 1727@Entry 1728@Component 1729struct Index { 1730 build() { 1731 Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { 1732 Button() { 1733 Text('testAesCipher') 1734 .fontSize(30) 1735 .fontWeight(FontWeight.Bold) 1736 }.type(ButtonType.Capsule) 1737 .margin({ 1738 top: 20 1739 }) 1740 .backgroundColor('#0D9FFB') 1741 .onClick(()=>{ 1742 testAesCipher(); 1743 }) 1744 } 1745 .width('100%') 1746 .height('100%') 1747 } 1748} 1749``` 1750 1751### Signing and Signature Verification 1752 1753The data to be sent can be signed with a unique signature for security purposes. Then, the receiver needs to verify the signature when receiving the data. 1754 1755The development procedure is as follows: 1756 17571. Generate a key. 17582. Use the key to sign the data to be sent. 17593. Export the signature key. 17604. Import the signature key. 17615. Verify the signature. 1762 1763**Supported key types**: 1764 1765Only **HksInit()** has requirements on parameters in **paramSet**. The other Init-Update-Finish APIs have no requirements on **paramSet**. 1766 1767| HUKS_ALG_ALGORITHM | HUKS_ALG_KEY_SIZE | HUKS_ALG_PURPOSE | HUKS_ALG_PADDING | HUKS_TAG_DIGEST | 1768| ------------------ | ------------------------------------------------------------ | ---------------------------------------------- | ----------------------- | ------------------------------------------------------------ | 1769| HUKS_ALG_RSA | HUKS_RSA_KEY_SIZE_512, HUKS_RSA_KEY_SIZE_768, HUKS_RSA_KEY_SIZE_1024, HUKS_RSA_KEY_SIZE_2048, HUKS_RSA_KEY_SIZE_3072, HUKS_RSA_KEY_SIZE_4096| HUKS_KEY_PURPOSE_SIGN HUKS_KEY_PURPOSE_VERIFY | HUKS_PADDING_PKCS1_V1_5 | HUKS_DIGEST_MD5, HUKS_DIGEST_NONE, HUKS_DIGEST_SHA1, HUKS_DIGEST_SHA224, HUKS_DIGEST_SHA384, HUKS_DIGEST_SHA512| 1770| HUKS_ALG_RSA | HUKS_RSA_KEY_SIZE_512, HUKS_RSA_KEY_SIZE_768, HUKS_RSA_KEY_SIZE_1024, HUKS_RSA_KEY_SIZE_2048, HUKS_RSA_KEY_SIZE_3072, HUKS_RSA_KEY_SIZE_4096| HUKS_KEY_PURPOSE_SIGN HUKS_KEY_PURPOSE_VERIFY | HUKS_PADDING_PSS | HUKS_DIGEST_SHA1, HUKS_DIGEST_SHA224, HUKS_DIGEST_SHA256, HUKS_DIGEST_SHA384, HUKS_DIGEST_SHA512| 1771| HUKS_ALG_DSA | HUKS_RSA_KEY_SIZE_1024 | HUKS_KEY_PURPOSE_SIGN HUKS_KEY_PURPOSE_VERIFY | Optional | HUKS_DIGEST_SHA1, HUKS_DIGEST_SHA224, HUKS_DIGEST_SHA256, HUKS_DIGEST_SHA384, HUKS_DIGEST_SHA512| 1772| HUKS_ALG_ECC | HUKS_ECC_KEY_SIZE_224, HUKS_ECC_KEY_SIZE_256, HUKS_ECC_KEY_SIZE_384, HUKS_ECC_KEY_SIZE_521| HUKS_KEY_PURPOSE_SIGN HUKS_KEY_PURPOSE_VERIFY | Optional | HUKS_DIGEST_NONE, HUKS_DIGEST_SHA1, HUKS_DIGEST_SHA224, HUKS_DIGEST_SHA256, HUKS_DIGEST_SHA384, HUKS_DIGEST_SHA512| 1773 1774The signing and signature verification using Ed25519 involves a hash operation in the algorithm engine. Therefore, the Init-Update-Finish processing is special. 1775 1776In the **update()** process, **inData** is sent to HUKS Core and recorded in a .ctx file, without performing hash operation. The signing and signature verification calculations are performed on the combined **inData** in the **finish()** operation. 1777 1778| HUKS_ALG_ALGORITHM | HUKS_ALG_KEY_SIZE | HUKS_ALG_PURPOSE | 1779| ------------------ | ---------------------------- | ----------------------------------------------- | 1780| HUKS_ALG_ED25519 | HUKS_CURVE25519_KEY_SIZE_256 | HUKS_KEY_PURPOSE_SIGN HUKS_KEY_PURPOSE_VERIFY | 1781 1782> **NOTE**<br> 1783> 1784> The key alias cannot exceed 64 bytes. 1785 1786Before you get started, understand the following variables: 1787 1788| Parameter | Type | Mandatory| Description | 1789| ----------------- | ----------- | ---- | ------------------------ | 1790| generateKeyAlias | string | Yes | Alias of the key to generate. | 1791| importKeyAlias | string | Yes | Alias of the key imported. | 1792| genrateKeyOptions | HuksOptions | Yes | Tags required for generating the key.| 1793| signOptions | HuksOptions | Yes | Tags required for signing.| 1794| verifyOptions | HuksOptions | Yes | Tags required for verifying the signature.| 1795 1796For details about the APIs, see [HUKS](../reference/apis/js-apis-huks.md). 1797 1798**Example** 1799 1800```ts 1801/*The Sign() and Verify() operations support RSA, ECC, SM2, ED25519, and DSA keys. 1802 * 1803 * The following uses an SM2 key in callback-based APIs as an example. 1804 */ 1805import huks from '@ohos.security.huks'; 1806 1807function StringToUint8Array(str) { 1808 let arr = []; 1809 for (let i = 0, j = str.length; i < j; ++i) { 1810 arr.push(str.charCodeAt(i)); 1811 } 1812 return new Uint8Array(arr); 1813} 1814 1815async function publicGenKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) { 1816 console.info(`enter callback generateKeyItem`); 1817 try { 1818 await generateKeyItem(keyAlias, huksOptions) 1819 .then((data) => { 1820 console.info(`callback: generateKeyItem success, data = ${JSON.stringify(data)}`); 1821 }) 1822 .catch(error => { 1823 console.error(`callback: generateKeyItem failed, code: ${error.code}, msg: ${error.message}`); 1824 }); 1825 } catch (error) { 1826 console.error(`callback: generateKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`); 1827 } 1828} 1829 1830function generateKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) { 1831 return new Promise((resolve, reject) => { 1832 try { 1833 huks.generateKeyItem(keyAlias, huksOptions, function (error, data) { 1834 if (error) { 1835 reject(error); 1836 } else { 1837 resolve(data); 1838 } 1839 }); 1840 } catch (error) { 1841 throw(error); 1842 } 1843 }); 1844} 1845 1846async function publicInitFunc(keyAlias:string, huksOptions:huks.HuksOptions) { 1847 console.info(`enter callback doInit`); 1848 try { 1849 await initSession(keyAlias, huksOptions) 1850 .then ((data) => { 1851 console.info(`callback1: doInit success, data = ${JSON.stringify(data)}`); 1852 handle = data.handle; 1853 }) 1854 .catch((error) => { 1855 console.error(`callback1: doInit failed, code: ${error.code}, msg: ${error.message}`); 1856 }); 1857 } catch (error) { 1858 console.error(`callback: doInit input arg invalid, code: ${error.code}, msg: ${error.message}`); 1859 } 1860} 1861 1862function initSession(keyAlias:string, huksOptions:huks.HuksOptions) : Promise<huks.HuksSessionHandle> { 1863 return new Promise((resolve, reject) => { 1864 try { 1865 huks.initSession(keyAlias, huksOptions, function (error, data) { 1866 if (error) { 1867 reject(error); 1868 } else { 1869 resolve(data); 1870 } 1871 }); 1872 } catch (error) { 1873 throw(error); 1874 } 1875 }); 1876} 1877 1878async function publicUpdateFunc(handle:number, huksOptions:huks.HuksOptions) { 1879 console.info(`enter callback doUpdate`); 1880 try { 1881 await updateSession(handle, huksOptions) 1882 .then ((data) => { 1883 console.info(`callback: doUpdate success, data = ${JSON.stringify(data)}`); 1884 }) 1885 .catch(error => { 1886 console.error(`callback: doUpdate failed, code: ${error.code}, msg: ${error.message}`); 1887 }); 1888 } catch (error) { 1889 console.error(`callback: doUpdate input arg invalid, code: ${error.code}, msg: ${error.message}`); 1890 } 1891} 1892 1893function updateSession(handle:number, huksOptions:huks.HuksOptions) : Promise<huks.HuksReturnResult> { 1894 return new Promise((resolve, reject) => { 1895 try { 1896 huks.updateSession(handle, huksOptions, function (error, data) { 1897 if (error) { 1898 reject(error); 1899 } else { 1900 resolve(data); 1901 } 1902 }); 1903 } catch (error) { 1904 throw(error); 1905 } 1906 }); 1907} 1908 1909async function publicFinishFunc(handle:number, huksOptions:huks.HuksOptions) { 1910 console.info(`enter callback doFinish`); 1911 try { 1912 await finishSession(handle, huksOptions) 1913 .then ((data) => { 1914 finishOutData = data.outData;; 1915 console.info(`callback: doFinish success, data = ${JSON.stringify(data)}`); 1916 }) 1917 .catch(error => { 1918 console.error(`callback: doFinish failed, code: ${error.code}, msg: ${error.message}`); 1919 }); 1920 } catch (error) { 1921 console.error(`callback: doFinish input arg invalid, code: ${error.code}, msg: ${error.message}`); 1922 } 1923} 1924 1925function finishSession(handle:number, huksOptions:huks.HuksOptions) : Promise<huks.HuksReturnResult> { 1926 return new Promise((resolve, reject) => { 1927 try { 1928 huks.finishSession(handle, huksOptions, function (error, data) { 1929 if (error) { 1930 reject(error); 1931 } else { 1932 resolve(data); 1933 } 1934 }); 1935 } catch (error) { 1936 throw(error); 1937 } 1938 }); 1939} 1940 1941async function publicExportKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) { 1942 console.info(`enter callback export`); 1943 try { 1944 await exportKeyItem(keyAlias, huksOptions) 1945 .then ((data) => { 1946 console.info(`callback: exportKeyItem success, data = ${JSON.stringify(data)}`); 1947 exportKey = data.outData; 1948 }) 1949 .catch(error => { 1950 console.error(`callback: exportKeyItem failed, code: ${error.code}, msg: ${error.message}`); 1951 }); 1952 } catch (error) { 1953 console.error(`callback: exportKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`); 1954 } 1955} 1956 1957function exportKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) : Promise<huks.HuksReturnResult> { 1958 return new Promise((resolve, reject) => { 1959 try { 1960 huks.exportKeyItem(keyAlias, huksOptions, function (error, data) { 1961 if (error) { 1962 reject(error); 1963 } else { 1964 resolve(data); 1965 } 1966 }); 1967 } catch (error) { 1968 throw(error); 1969 } 1970 }); 1971} 1972 1973async function publicImportKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) { 1974 console.info(`enter promise importKeyItem`); 1975 try { 1976 await importKeyItem(keyAlias, huksOptions) 1977 .then ((data) => { 1978 console.info(`callback: importKeyItem success, data = ${JSON.stringify(data)}`); 1979 }) 1980 .catch(error => { 1981 console.error(`callback: importKeyItem failed, code: ${error.code}, msg: ${error.message}`); 1982 }); 1983 } catch (error) { 1984 console.error(`callback: importKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`); 1985 } 1986} 1987 1988function importKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) { 1989 return new Promise((resolve, reject) => { 1990 try { 1991 huks.importKeyItem(keyAlias, huksOptions, function (error, data) { 1992 if (error) { 1993 reject(error); 1994 } else { 1995 resolve(data); 1996 } 1997 }); 1998 } catch (error) { 1999 throw(error); 2000 } 2001 }); 2002} 2003 2004async function publicDeleteKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) { 2005 console.info(`enter callback deleteKeyItem`); 2006 try { 2007 await deleteKeyItem(keyAlias, huksOptions) 2008 .then ((data) => { 2009 console.info(`callback: deleteKeyItem key success, data = ${JSON.stringify(data)}`); 2010 }) 2011 .catch(error => { 2012 console.error(`callback: deleteKeyItem failed, code: ${error.code}, msg: ${error.message}`); 2013 }); 2014 } catch (error) { 2015 console.error(`callback: deleteKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`); 2016 } 2017} 2018 2019function deleteKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) { 2020 return new Promise((resolve, reject) => { 2021 try { 2022 huks.deleteKeyItem(keyAlias, huksOptions, function (error, data) { 2023 if (error) { 2024 reject(error); 2025 } else { 2026 resolve(data); 2027 } 2028 }); 2029 } catch (error) { 2030 throw(error); 2031 } 2032 }); 2033} 2034 2035let signVerifyInData1 = 'signVerifyInDataForTestFirstText'; 2036let signVerifyInData2 = 'signVerifyInDataForTestSecondText'; 2037let signVerifyInData = [signVerifyInData1, signVerifyInData2]; 2038let generateKeyAlias = 'generateKeyAliasForTest'; 2039let importKeyAlias = 'importKeyAliasForTest'; 2040let handle; 2041let exportKey; 2042let finishOutData; 2043 2044/* Configure the parameters for generating the key. */ 2045let generateKeyProperties = new Array(); 2046generateKeyProperties[0] = { 2047 tag: huks.HuksTag.HUKS_TAG_ALGORITHM, 2048 value: huks.HuksKeyAlg.HUKS_ALG_SM2, 2049} 2050generateKeyProperties[1] = { 2051 tag: huks.HuksTag.HUKS_TAG_PURPOSE, 2052 value: 2053 huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_SIGN | 2054 huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_VERIFY, 2055} 2056generateKeyProperties[2] = { 2057 tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, 2058 value: huks.HuksKeySize.HUKS_SM2_KEY_SIZE_256, 2059} 2060generateKeyProperties[3] = { 2061 tag: huks.HuksTag.HUKS_TAG_DIGEST, 2062 value: huks.HuksKeyDigest.HUKS_DIGEST_SM3, 2063} 2064let genrateKeyOptions = { 2065 properties: generateKeyProperties, 2066 inData: new Uint8Array(new Array()) 2067} 2068 2069/* Configure the parameters for signing. */ 2070let signProperties = new Array(); 2071signProperties[0] = { 2072 tag: huks.HuksTag.HUKS_TAG_ALGORITHM, 2073 value: huks.HuksKeyAlg.HUKS_ALG_SM2, 2074} 2075signProperties[1] = { 2076 tag: huks.HuksTag.HUKS_TAG_PURPOSE, 2077 value: 2078 huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_SIGN 2079} 2080signProperties[2] = { 2081 tag: huks.HuksTag.HUKS_TAG_DIGEST, 2082 value: huks.HuksKeyDigest.HUKS_DIGEST_SM3, 2083} 2084signProperties[3] = { 2085 tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, 2086 value: huks.HuksKeySize.HUKS_SM2_KEY_SIZE_256, 2087} 2088let signOptions = { 2089 properties: signProperties, 2090 inData: new Uint8Array(new Array()) 2091} 2092 2093/* Configure the parameters for signature verification. */ 2094let verifyProperties = new Array(); 2095verifyProperties[0] = { 2096 tag: huks.HuksTag.HUKS_TAG_ALGORITHM, 2097 value: huks.HuksKeyAlg.HUKS_ALG_SM2, 2098} 2099verifyProperties[1] = { 2100 tag: huks.HuksTag.HUKS_TAG_PURPOSE, 2101 value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_VERIFY 2102} 2103verifyProperties[2] = { 2104 tag: huks.HuksTag.HUKS_TAG_DIGEST, 2105 value: huks.HuksKeyDigest.HUKS_DIGEST_SM3, 2106} 2107verifyProperties[3] = { 2108 tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, 2109 value: huks.HuksKeySize.HUKS_SM2_KEY_SIZE_256, 2110} 2111let verifyOptions = { 2112 properties: verifyProperties, 2113 inData: new Uint8Array(new Array()) 2114} 2115 2116async function testSm2SignVerify() { 2117 /* Generate a key. */ 2118 await publicGenKeyFunc(generateKeyAlias, genrateKeyOptions); 2119 2120 /* Generate a signature. */ 2121 let signHandle; 2122 let signFinishOutData; 2123 await publicInitFunc(generateKeyAlias, signOptions); 2124 2125 signHandle = handle; 2126 for (var index = 0; index < signVerifyInData.length; index++) { 2127 signOptions.inData = StringToUint8Array(signVerifyInData[index]); 2128 await publicUpdateFunc(signHandle, signOptions); 2129 } 2130 2131 signOptions.inData = new Uint8Array(new Array()); 2132 await publicFinishFunc(signHandle, signOptions); 2133 signFinishOutData = finishOutData; 2134 2135 /* Export the key. */ 2136 await publicExportKeyFunc(generateKeyAlias, genrateKeyOptions); 2137 2138 /* Import the key. */ 2139 verifyOptions.inData = exportKey; 2140 await publicImportKeyFunc(importKeyAlias, verifyOptions); 2141 2142 /* Verify the signature. */ 2143 let verifyHandle; 2144 await publicInitFunc(importKeyAlias, verifyOptions); 2145 2146 verifyHandle = handle; 2147 2148 for (var index = 0; index < signVerifyInData.length; index++) { 2149 verifyOptions.inData = StringToUint8Array(signVerifyInData[index]); 2150 await publicUpdateFunc(verifyHandle, verifyOptions); 2151 } 2152 2153 verifyOptions.inData = signFinishOutData; 2154 await publicFinishFunc(verifyHandle, verifyOptions); 2155 2156 await publicDeleteKeyFunc(generateKeyAlias, genrateKeyOptions); 2157 await publicDeleteKeyFunc(importKeyAlias, genrateKeyOptions); 2158} 2159 2160@Entry 2161@Component 2162struct Index { 2163 build() { 2164 Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { 2165 Button() { 2166 Text('testSm2SignVerify') 2167 .fontSize(30) 2168 .fontWeight(FontWeight.Bold) 2169 }.type(ButtonType.Capsule) 2170 .margin({ 2171 top: 20 2172 }) 2173 .backgroundColor('#0D9FFB') 2174 .onClick(()=>{ 2175 testSm2SignVerify(); 2176 }) 2177 } 2178 .width('100%') 2179 .height('100%') 2180 } 2181} 2182``` 2183 2184### Key Agreement 2185 2186Two or more objects communicate with each other based on the same session key. 2187 2188The development procedure is as follows: 2189 21901. Generate two keys. 21912. Export the keys separately. 21923. Perform key agreement. 2193 2194**Supported key types**: 2195 2196The **HksInit()** and **HksFinish()** APIs have requirements on **paramSet**. The **HksUpdate()** API has no requirements on **paramSet**. 2197 2198Requirements of **HksInit()** for **paramSet**: 2199 2200| HUKS_ALG_ALGORITHM | HUKS_ALG_KEY_SIZE | HUKS_ALG_PURPOSE | 2201| ------------------ | ------------------------------------------------------------ | ---------------------- | 2202| HUKS_ALG_ECDH | HUKS_ECC_KEY_SIZE_224, HUKS_ECC_KEY_SIZE_256, HUKS_ECC_KEY_SIZE_384, HUKS_ECC_KEY_SIZE_521| HUKS_KEY_PURPOSE_AGREE | 2203| HUKS_ALG_DH | HUKS_DH_KEY_SIZE_2048, HUKS_DH_KEY_SIZE_3072, HUKS_DH_KEY_SIZE_4096| HUKS_KEY_PURPOSE_AGREE | 2204| HUKS_ALG_X25519 | HUKS_CURVE25519_KEY_SIZE_256 | HUKS_KEY_PURPOSE_AGREE | 2205 2206Requirements of **HksFinish()** for **paramSet**: 2207 2208The derived key is used as a symmetric key. 2209 2210| HUKS_TAG_KEY_STORAGE_FLAG | HUKS_TAG_KEY_ALIAS | HUKS_TAG_IS_KEY_ALIAS | HUKS_TAG_ALGORITHM | HUKS_TAG_KEY_SIZE | HUKS_TAG_PURPOSE | HUKS_TAG_PADDING | HUKS_TAG_DIGEST | HUKS_TAG_BLOCK_MODE | 2211| ------------------------------ | ------------------ | --------------------- | ------------------ | ------------------------------------------------------------ | -------------------------------------------------- | ------------------ | ------------------------------------------------------------ | ------------------------------------------- | 2212| **HUKS_STORAGE_TEMP** or not set| Not required | TRUE | Not required | Not required | Not required | Not required | Not required | Not required | 2213| HUKS_STORAGE_PERSISTENT | (Mandatory) Maximum 64 bytes.| TRUE | HUKS_ALG_AES | HUKS_AES_KEY_SIZE_128, HUKS_AES_KEY_SIZE_192, HUKS_AES_KEY_SIZE_256| HUKS_KEY_PURPOSE_ENCRYPT or HUKS_KEY_PURPOSE_DECRYPT| HUKS_PADDING_PKCS7 | Optional | HUKS_MODE_CCM HUKS_MODE_GCM HUKS_MODE_CTP | 2214| HUKS_STORAGE_PERSISTENT | (Mandatory) Maximum 64 bytes.| TRUE | HUKS_ALG_AES | HUKS_AES_KEY_SIZE_128, HUKS_AES_KEY_SIZE_192, HUKS_AES_KEY_SIZE_256| HUKS_KEY_PURPOSE_DERIVE | Optional | HUKS_DIGEST_SHA256, HUKS_DIGEST_SHA384, HUKS_DIGEST_SHA512 | Optional | 2215| HUKS_STORAGE_PERSISTENT | (Mandatory) Maximum 64 bytes.| TRUE | HUKS_ALG_HMAC | Multiple of 8, in bits | HUKS_KEY_PURPOSE_MAC | Optional | HUKS_DIGEST_SHA1, HUKS_DIGEST_SHA224, HUKS_DIGEST_SHA256, HUKS_DIGEST_SHA384, HUKS_DIGEST_SHA512| Optional | 2216 2217> **NOTE**<br> 2218> 2219> The length of the key after agreement (converted into bits) must be greater than or equal to the selected **HUKS_TAG_KEY_SIZE**. 2220> 2221> The key alias cannot exceed 64 bytes. 2222 2223Before you get started, understand the following variables: 2224 2225| Parameter | Type | Mandatory| Description | 2226| ------------------- | ----------- | ---- | -------------------------------------- | 2227| srcKeyAliasFirst | string | Yes | Alias of the key generated. | 2228| srcKeyAliasSecond | string | Yes | Alias of key 2 generated. | 2229| huksOptions | HuksOptions | Yes | Tags required for generating the key. | 2230| finishOptionsFrist | HuksOptions | Yes | Tags required for key agreement. | 2231| finishOptionsSecond | HuksOptions | Yes | Tags required for key agreement.| 2232 2233For details about the APIs, see [HUKS](../reference/apis/js-apis-huks.md). 2234 2235**Example** 2236 2237```ts 2238/* The agree() operation supports ECDH, DH, and X25519 keys. 2239 * 2240 * The following uses the Promise() operation of an X25519 256-bit TEMP key as an example. 2241 */ 2242import huks from '@ohos.security.huks'; 2243 2244function StringToUint8Array(str) { 2245 let arr = []; 2246 for (let i = 0, j = str.length; i < j; ++i) { 2247 arr.push(str.charCodeAt(i)); 2248 } 2249 return new Uint8Array(arr); 2250} 2251 2252async function publicGenKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) { 2253 console.info(`enter callback generateKeyItem`); 2254 try { 2255 await generateKeyItem(keyAlias, huksOptions) 2256 .then((data) => { 2257 console.info(`callback: generateKeyItem success, data = ${JSON.stringify(data)}`); 2258 }) 2259 .catch(error => { 2260 console.error(`callback: generateKeyItem failed, code: ${error.code}, msg: ${error.message}`); 2261 }); 2262 } catch (error) { 2263 console.error(`callback: generateKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`); 2264 } 2265} 2266 2267function generateKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) { 2268 return new Promise((resolve, reject) => { 2269 try { 2270 huks.generateKeyItem(keyAlias, huksOptions, function (error, data) { 2271 if (error) { 2272 reject(error); 2273 } else { 2274 resolve(data); 2275 } 2276 }); 2277 } catch (error) { 2278 throw(error); 2279 } 2280 }); 2281} 2282 2283async function publicInitFunc(keyAlias:string, huksOptions:huks.HuksOptions) { 2284 console.info(`enter callback doInit`); 2285 try { 2286 await initSession(keyAlias, huksOptions) 2287 .then ((data) => { 2288 console.info(`callback1: doInit success, data = ${JSON.stringify(data)}`); 2289 handle = data.handle; 2290 }) 2291 .catch((error) => { 2292 console.error(`callback1: doInit failed, code: ${error.code}, msg: ${error.message}`); 2293 }); 2294 } catch (error) { 2295 console.error(`callback: doInit input arg invalid, code: ${error.code}, msg: ${error.message}`); 2296 } 2297} 2298 2299function initSession(keyAlias:string, huksOptions:huks.HuksOptions) : Promise<huks.HuksSessionHandle> { 2300 return new Promise((resolve, reject) => { 2301 try { 2302 huks.initSession(keyAlias, huksOptions, function (error, data) { 2303 if (error) { 2304 reject(error); 2305 } else { 2306 resolve(data); 2307 } 2308 }); 2309 } catch (error) { 2310 throw(error); 2311 } 2312 }); 2313} 2314 2315async function publicUpdateFunc(handle:number, huksOptions:huks.HuksOptions) { 2316 console.info(`enter callback doUpdate`); 2317 try { 2318 await updateSession(handle, huksOptions) 2319 .then ((data) => { 2320 console.info(`callback: doUpdate success, data = ${JSON.stringify(data)}`); 2321 }) 2322 .catch(error => { 2323 console.error(`callback: doUpdate failed, code: ${error.code}, msg: ${error.message}`); 2324 }); 2325 } catch (error) { 2326 console.error(`callback: doUpdate input arg invalid, code: ${error.code}, msg: ${error.message}`); 2327 } 2328} 2329 2330function updateSession(handle:number, huksOptions:huks.HuksOptions) : Promise<huks.HuksReturnResult> { 2331 return new Promise((resolve, reject) => { 2332 try { 2333 huks.updateSession(handle, huksOptions, function (error, data) { 2334 if (error) { 2335 reject(error); 2336 } else { 2337 resolve(data); 2338 } 2339 }); 2340 } catch (error) { 2341 throw(error); 2342 } 2343 }); 2344} 2345 2346async function publicFinishFunc(handle:number, huksOptions:huks.HuksOptions) { 2347 console.info(`enter callback doFinish`); 2348 try { 2349 await finishSession(handle, huksOptions) 2350 .then ((data) => { 2351 console.info(`callback: doFinish success, data = ${JSON.stringify(data)}`); 2352 }) 2353 .catch(error => { 2354 console.error(`callback: doFinish failed, code: ${error.code}, msg: ${error.message}`); 2355 }); 2356 } catch (error) { 2357 console.error(`callback: doFinish input arg invalid, code: ${error.code}, msg: ${error.message}`); 2358 } 2359} 2360 2361function finishSession(handle:number, huksOptions:huks.HuksOptions) : Promise<huks.HuksReturnResult> { 2362 return new Promise((resolve, reject) => { 2363 try { 2364 huks.finishSession(handle, huksOptions, function (error, data) { 2365 if (error) { 2366 reject(error); 2367 } else { 2368 resolve(data); 2369 } 2370 }); 2371 } catch (error) { 2372 throw(error); 2373 } 2374 }); 2375} 2376 2377async function publicExportKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) { 2378 console.info(`enter callback export`); 2379 try { 2380 await exportKeyItem(keyAlias, huksOptions) 2381 .then ((data) => { 2382 console.info(`callback: exportKeyItem success, data = ${JSON.stringify(data)}`); 2383 exportKey = data.outData; 2384 }) 2385 .catch(error => { 2386 console.error(`callback: exportKeyItem failed, code: ${error.code}, msg: ${error.message}`); 2387 }); 2388 } catch (error) { 2389 console.error(`callback: exportKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`); 2390 } 2391} 2392 2393function exportKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) : Promise<huks.HuksReturnResult> { 2394 return new Promise((resolve, reject) => { 2395 try { 2396 huks.exportKeyItem(keyAlias, huksOptions, function (error, data) { 2397 if (error) { 2398 reject(error); 2399 } else { 2400 resolve(data); 2401 } 2402 }); 2403 } catch (error) { 2404 throw(error); 2405 } 2406 }); 2407} 2408 2409async function publicDeleteKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) { 2410 console.info(`enter callback deleteKeyItem`); 2411 try { 2412 await deleteKeyItem(keyAlias, huksOptions) 2413 .then ((data) => { 2414 console.info(`callback: deleteKeyItem key success, data = ${JSON.stringify(data)}`); 2415 }) 2416 .catch(error => { 2417 console.error(`callback: deleteKeyItem failed, code: ${error.code}, msg: ${error.message}`); 2418 }); 2419 } catch (error) { 2420 console.error(`callback: deleteKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`); 2421 } 2422} 2423 2424function deleteKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) { 2425 return new Promise((resolve, reject) => { 2426 try { 2427 huks.deleteKeyItem(keyAlias, huksOptions, function (error, data) { 2428 if (error) { 2429 reject(error); 2430 } else { 2431 resolve(data); 2432 } 2433 }); 2434 } catch (error) { 2435 throw(error); 2436 } 2437 }); 2438} 2439 2440let srcKeyAliasFirst = "AgreeX25519KeyFirstAlias"; 2441let srcKeyAliasSecond = "AgreeX25519KeySecondAlias"; 2442let agreeX25519InData = 'AgreeX25519TestIndata'; 2443let handle; 2444let exportKey; 2445let exportKeyFrist; 2446let exportKeySecond; 2447 2448async function testAgree() { 2449 /* Configure the parameters for generating the key. */ 2450 let properties = new Array(); 2451 properties[0] = { 2452 tag: huks.HuksTag.HUKS_TAG_ALGORITHM, 2453 value: huks.HuksKeyAlg.HUKS_ALG_X25519, 2454 } 2455 properties[1] = { 2456 tag: huks.HuksTag.HUKS_TAG_PURPOSE, 2457 value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_AGREE, 2458 } 2459 properties[2] = { 2460 tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, 2461 value: huks.HuksKeySize.HUKS_CURVE25519_KEY_SIZE_256, 2462 } 2463 properties[3] = { 2464 tag: huks.HuksTag.HUKS_TAG_DIGEST, 2465 value: huks.HuksKeyDigest.HUKS_DIGEST_NONE, 2466 } 2467 properties[4] = { 2468 tag: huks.HuksTag.HUKS_TAG_PADDING, 2469 value: huks.HuksKeyPadding.HUKS_PADDING_NONE, 2470 } 2471 properties[5] = { 2472 tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE, 2473 value: huks.HuksCipherMode.HUKS_MODE_CBC, 2474 } 2475 let HuksOptions = { 2476 properties: properties, 2477 inData: new Uint8Array(new Array()) 2478 } 2479 2480 /* 1. Generate two keys and export them. */ 2481 await publicGenKeyFunc(srcKeyAliasFirst, HuksOptions); 2482 await publicGenKeyFunc(srcKeyAliasSecond, HuksOptions); 2483 2484 await publicExportKeyFunc(srcKeyAliasFirst, HuksOptions); 2485 exportKeyFrist = exportKey; 2486 await publicExportKeyFunc(srcKeyAliasFirst, HuksOptions); 2487 exportKeySecond = exportKey; 2488 2489 /* Configure parameters for the first key agreement. */ 2490 let finishProperties = new Array(); 2491 finishProperties[0] = { 2492 tag: huks.HuksTag.HUKS_TAG_KEY_STORAGE_FLAG, 2493 value: huks.HuksKeyStorageType.HUKS_STORAGE_TEMP, 2494 } 2495 finishProperties[1] = { 2496 tag: huks.HuksTag.HUKS_TAG_IS_KEY_ALIAS, 2497 value: true 2498 } 2499 finishProperties[2] = { 2500 tag: huks.HuksTag.HUKS_TAG_ALGORITHM, 2501 value: huks.HuksKeyAlg.HUKS_ALG_AES, 2502 } 2503 finishProperties[3] = { 2504 tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, 2505 value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_256, 2506 } 2507 finishProperties[4] = { 2508 tag: huks.HuksTag.HUKS_TAG_PURPOSE, 2509 value: 2510 huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT | 2511 huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT, 2512 } 2513 finishProperties[5] = { 2514 tag: huks.HuksTag.HUKS_TAG_DIGEST, 2515 value: huks.HuksKeyDigest.HUKS_DIGEST_NONE, 2516 } 2517 finishProperties[6] = { 2518 tag: huks.HuksTag.HUKS_TAG_KEY_ALIAS, 2519 value: StringToUint8Array(srcKeyAliasFirst+ 'final'), 2520 } 2521 finishProperties[7] = { 2522 tag: huks.HuksTag.HUKS_TAG_PADDING, 2523 value: huks.HuksKeyPadding.HUKS_PADDING_NONE, 2524 } 2525 finishProperties[8] = { 2526 tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE, 2527 value: huks.HuksCipherMode.HUKS_MODE_ECB, 2528 } 2529 let finishOptionsFrist = { 2530 properties: finishProperties, 2531 inData: StringToUint8Array(agreeX25519InData) 2532 } 2533 2534 /* Obtain the first agreed key. */ 2535 await publicInitFunc(srcKeyAliasFirst, HuksOptions); 2536 HuksOptions.inData = exportKeySecond; 2537 await publicUpdateFunc(handle, HuksOptions); 2538 await publicFinishFunc(handle, finishOptionsFrist); 2539 2540 /* Configure parameters for the second key agreement. */ 2541 let finishOptionsSecond = { 2542 properties: finishProperties, 2543 inData: StringToUint8Array(agreeX25519InData) 2544 } 2545 finishOptionsSecond.properties.splice(6, 1, { 2546 tag: huks.HuksTag.HUKS_TAG_KEY_ALIAS, 2547 value: StringToUint8Array(srcKeyAliasSecond + 'final'), 2548 }) 2549 2550 /* Obtain the second agreed key. */ 2551 await publicInitFunc(srcKeyAliasSecond, HuksOptions); 2552 HuksOptions.inData = exportKeyFrist; 2553 await publicUpdateFunc(handle, HuksOptions); 2554 await publicFinishFunc(handle, finishOptionsSecond); 2555 2556 2557 await publicDeleteKeyFunc(srcKeyAliasFirst, HuksOptions); 2558 await publicDeleteKeyFunc(srcKeyAliasSecond, HuksOptions); 2559} 2560 2561@Entry 2562@Component 2563struct Index { 2564 build() { 2565 Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { 2566 Button() { 2567 Text('testAgree') 2568 .fontSize(30) 2569 .fontWeight(FontWeight.Bold) 2570 }.type(ButtonType.Capsule) 2571 .margin({ 2572 top: 20 2573 }) 2574 .backgroundColor('#0D9FFB') 2575 .onClick(()=>{ 2576 testAgree(); 2577 }) 2578 } 2579 .width('100%') 2580 .height('100%') 2581 } 2582} 2583``` 2584 2585### Key Derivation 2586 2587Derive one or more keys from a key. 2588 2589The development procedure is as follows: 2590 25911. Generate a key. 25922. Derive a key. 2593 2594**Supported key types**: 2595 2596The **HksInit()** and **HksFinish()** APIs have requirements on **paramSet**. The **HksUpdate()** API has no requirements on **paramSet**. 2597 2598Requirements of **HksInit()** for **paramSet**: 2599 2600| HUKS_TAG_ALGORITHM | HUKS_TAG_PURPOSE | HUKS_TAG_DIGEST | HUKS_TAG_DERIVE_KEY_SIZE | 2601| ------------------------------------------------------------ | ----------------------- | ---------------------------------------------------------- | ------------------------ | 2602| HUKS_ALG_HKDF (supported key lengths: HUKS_AES_KEY_SIZE_128, HUKS_AES_KEY_SIZE_192, HUKS_AES_KEY_SIZE_256)| HUKS_KEY_PURPOSE_DERIVE | HUKS_DIGEST_SHA256 HUKS_DIGEST_SHA384 HUKS_DIGEST_SHA512 | Mandatory | 2603| HUKS_ALG_PBKDF2 (supported key lengths: HUKS_AES_KEY_SIZE_128, HUKS_AES_KEY_SIZE_192, HUKS_AES_KEY_SIZE_256)| HUKS_KEY_PURPOSE_DERIVE | HUKS_DIGEST_SHA256, HUKS_DIGEST_SHA384, HUKS_DIGEST_SHA512| Mandatory | 2604 2605Requirements of **HksFinish()** for **paramSet**: 2606 2607The derived key is used as a symmetric key. 2608 2609| HUKS_TAG_KEY_STORAGE_FLAG | HUKS_TAG_KEY_ALIAS | HUKS_TAG_IS_KEY_ALIAS | HUKS_TAG_ALGORITHM | HUKS_TAG_KEY_SIZE | HUKS_TAG_PURPOSE | HUKS_TAG_PADDING | HUKS_TAG_DIGEST | HUKS_TAG_BLOCK_MODE | 2610| ------------------------------ | ------------------ | --------------------- | ------------------ | ------------------------------------------------------------ | -------------------------------------------------- | ------------------------------------- | ------------------------------------------------------------ | ------------------------------------------- | 2611| **HUKS_STORAGE_TEMP** or not set| Not required | TRUE | Not required | Not required | Not required | Not required | Not required | Not required | 2612| HUKS_STORAGE_PERSISTENT | (Mandatory) Maximum 64 bytes.| TRUE | HUKS_ALG_AES | HUKS_AES_KEY_SIZE_128, HUKS_AES_KEY_SIZE_192, HUKS_AES_KEY_SIZE_256| HUKS_KEY_PURPOSE_ENCRYPT or HUKS_KEY_PURPOSE_DECRYPT| HUKS_PADDING_NONE, HUKS_PADDING_PKCS7| Optional | HUKS_MODE_CBC HUKS_MODE_ECB | 2613| HUKS_STORAGE_PERSISTENT | (Mandatory) Maximum 64 bytes.| TRUE | HUKS_ALG_AES | HUKS_AES_KEY_SIZE_128, HUKS_AES_KEY_SIZE_192, HUKS_AES_KEY_SIZE_256| HUKS_KEY_PURPOSE_ENCRYPT or HUKS_KEY_PURPOSE_DECRYPT| HUKS_PADDING_NONE | Optional | HUKS_MODE_CCM, HUKS_MODE_GCM, HUKS_MODE_CTR| 2614| HUKS_STORAGE_PERSISTENT | (Mandatory) Maximum 64 bytes.| TRUE | HUKS_ALG_AES | HUKS_AES_KEY_SIZE_128, HUKS_AES_KEY_SIZE_192, HUKS_AES_KEY_SIZE_256| HUKS_KEY_PURPOSE_DERIVE | Optional | HUKS_DIGEST_SHA256, HUKS_DIGEST_SHA384, HUKS_DIGEST_SHA512 | Optional | 2615| HUKS_STORAGE_PERSISTENT | (Mandatory) Maximum 64 bytes.| TRUE | HUKS_ALG_HMAC | Multiple of 8, in bits | HUKS_KEY_PURPOSE_MAC | Optional | HUKS_DIGEST_SHA1, HUKS_DIGEST_SHA224, HUKS_DIGEST_SHA256, HUKS_DIGEST_SHA384, HUKS_DIGEST_SHA512| Optional | 2616 2617> **NOTE**<br> 2618> 2619> The length of the derived key (converted into bits) must be greater than or equal to the selected **HUKS_TAG_KEY_SIZE**. 2620> 2621> The key alias cannot exceed 64 bytes. 2622 2623Before you get started, understand the following variables: 2624 2625| Parameter | Type | Mandatory| Description | 2626| ------------- | ----------- | ---- | ---------------- | 2627| srcKeyAlias | string | Yes | Alias of the key generated. | 2628| huksOptions | HuksOptions | Yes | Parameters for generating the key.| 2629| finishOptions | HuksOptions | Yes | Parameters for deriving a key.| 2630 2631For details about the APIs, see [HUKS](../reference/apis/js-apis-huks.md). 2632 2633**Example** 2634 2635```ts 2636/*The derive() operation supports HKDF and pbdkf keys. 2637 * 2638 * The following uses the Promise() operation of an HKDF256 key as an example. 2639 */ 2640import huks from '@ohos.security.huks'; 2641 2642function StringToUint8Array(str) { 2643 let arr = []; 2644 for (let i = 0, j = str.length; i < j; ++i) { 2645 arr.push(str.charCodeAt(i)); 2646 } 2647 return new Uint8Array(arr); 2648} 2649 2650async function publicGenKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) { 2651 console.info(`enter callback generateKeyItem`); 2652 try { 2653 await generateKeyItem(keyAlias, huksOptions) 2654 .then((data) => { 2655 console.info(`callback: generateKeyItem success, data = ${JSON.stringify(data)}`); 2656 }) 2657 .catch(error => { 2658 console.error(`callback: generateKeyItem failed, code: ${error.code}, msg: ${error.message}`); 2659 }); 2660 } catch (error) { 2661 console.error(`callback: generateKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`); 2662 } 2663} 2664 2665function generateKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) { 2666 return new Promise((resolve, reject) => { 2667 try { 2668 huks.generateKeyItem(keyAlias, huksOptions, function (error, data) { 2669 if (error) { 2670 reject(error); 2671 } else { 2672 resolve(data); 2673 } 2674 }); 2675 } catch (error) { 2676 throw(error); 2677 } 2678 }); 2679} 2680 2681async function publicInitFunc(keyAlias:string, huksOptions:huks.HuksOptions) { 2682 console.info(`enter promise doInit`); 2683 try { 2684 await huks.initSession(keyAlias, huksOptions) 2685 .then ((data) => { 2686 console.info(`promise: doInit success, data = ${JSON.stringify(data)}`); 2687 handle = data.handle; 2688 }) 2689 .catch(error => { 2690 console.error(`promise: doInit key failed, code: ${error.code}, msg: ${error.message}`); 2691 }); 2692 } catch (error) { 2693 console.error(`promise: doInit input arg invalid, code: ${error.code}, msg: ${error.message}`); 2694 } 2695} 2696 2697async function publicUpdateFunc(handle:number, huksOptions:huks.HuksOptions) { 2698 console.info(`enter callback doUpdate`); 2699 try { 2700 await updateSession(handle, huksOptions) 2701 .then ((data) => { 2702 console.info(`callback: doUpdate success, data = ${JSON.stringify(data)}`); 2703 }) 2704 .catch(error => { 2705 console.error(`callback: doUpdate failed, code: ${error.code}, msg: ${error.message}`); 2706 }); 2707 } catch (error) { 2708 console.error(`callback: doUpdate input arg invalid, code: ${error.code}, msg: ${error.message}`); 2709 } 2710} 2711 2712function updateSession(handle:number, huksOptions:huks.HuksOptions) : Promise<huks.HuksReturnResult> { 2713 return new Promise((resolve, reject) => { 2714 try { 2715 huks.updateSession(handle, huksOptions, function (error, data) { 2716 if (error) { 2717 reject(error); 2718 } else { 2719 resolve(data); 2720 } 2721 }); 2722 } catch (error) { 2723 throw(error); 2724 } 2725 }); 2726} 2727 2728async function publicFinishFunc(handle:number, huksOptions:huks.HuksOptions) { 2729 console.info(`enter callback doFinish`); 2730 try { 2731 await finishSession(handle, huksOptions) 2732 .then ((data) => { 2733 console.info(`callback: doFinish success, data = ${JSON.stringify(data)}`); 2734 }) 2735 .catch(error => { 2736 console.error(`callback: doFinish failed, code: ${error.code}, msg: ${error.message}`); 2737 }); 2738 } catch (error) { 2739 console.error(`callback: doFinish input arg invalid, code: ${error.code}, msg: ${error.message}`); 2740 } 2741} 2742 2743function finishSession(handle:number, huksOptions:huks.HuksOptions) : Promise<huks.HuksReturnResult> { 2744 return new Promise((resolve, reject) => { 2745 try { 2746 huks.finishSession(handle, huksOptions, function (error, data) { 2747 if (error) { 2748 reject(error); 2749 } else { 2750 resolve(data); 2751 } 2752 }); 2753 } catch (error) { 2754 throw(error); 2755 } 2756 }); 2757} 2758 2759async function publicDeleteKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) { 2760 console.info(`enter callback deleteKeyItem`); 2761 try { 2762 await deleteKeyItem(keyAlias, huksOptions) 2763 .then ((data) => { 2764 console.info(`callback: deleteKeyItem key success, data = ${JSON.stringify(data)}`); 2765 }) 2766 .catch(error => { 2767 console.error(`callback: deleteKeyItem failed, code: ${error.code}, msg: ${error.message}`); 2768 }); 2769 } catch (error) { 2770 console.error(`callback: deleteKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`); 2771 } 2772} 2773 2774function deleteKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) { 2775 return new Promise((resolve, reject) => { 2776 try { 2777 huks.deleteKeyItem(keyAlias, huksOptions, function (error, data) { 2778 if (error) { 2779 reject(error); 2780 } else { 2781 resolve(data); 2782 } 2783 }); 2784 } catch (error) { 2785 throw(error); 2786 } 2787 }); 2788} 2789 2790let deriveHkdfInData = "deriveHkdfTestIndata"; 2791let srcKeyAlias = "deriveHkdfKeyAlias"; 2792let handle; 2793let HuksKeyDeriveKeySize = 32; 2794 2795async function testDerive() { 2796 /* Configure the parameters for generating the key. */ 2797 let properties = new Array(); 2798 properties[0] = { 2799 tag: huks.HuksTag.HUKS_TAG_ALGORITHM, 2800 value: huks.HuksKeyAlg.HUKS_ALG_AES, 2801 } 2802 properties[1] = { 2803 tag: huks.HuksTag.HUKS_TAG_PURPOSE, 2804 value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DERIVE, 2805 } 2806 properties[2] = { 2807 tag: huks.HuksTag.HUKS_TAG_DIGEST, 2808 value: huks.HuksKeyDigest.HUKS_DIGEST_SHA256, 2809 } 2810 properties[3] = { 2811 tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, 2812 value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_128, 2813 } 2814 let huksOptions = { 2815 properties: properties, 2816 inData: new Uint8Array(new Array()) 2817 } 2818 2819 /* Generate a key. */ 2820 await publicGenKeyFunc(srcKeyAlias, huksOptions); 2821 2822 /* Modify the parameter set for init(). */ 2823 huksOptions.properties.splice(0, 1, { 2824 tag: huks.HuksTag.HUKS_TAG_ALGORITHM, 2825 value: huks.HuksKeyAlg.HUKS_ALG_HKDF, 2826 }); 2827 huksOptions.properties.splice(3, 1, { 2828 tag: huks.HuksTag.HUKS_TAG_DERIVE_KEY_SIZE, 2829 value: HuksKeyDeriveKeySize, 2830 }); 2831 2832 let finishProperties = new Array(); 2833 finishProperties[0] = { 2834 tag: huks.HuksTag.HUKS_TAG_KEY_STORAGE_FLAG, 2835 value: huks.HuksKeyStorageType.HUKS_STORAGE_PERSISTENT, 2836 } 2837 finishProperties[1] = { 2838 tag: huks.HuksTag.HUKS_TAG_IS_KEY_ALIAS, 2839 value: true, 2840 } 2841 finishProperties[2] = { 2842 tag: huks.HuksTag.HUKS_TAG_ALGORITHM, 2843 value: huks.HuksKeyAlg.HUKS_ALG_AES, 2844 } 2845 finishProperties[3] = { 2846 tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, 2847 value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_256, 2848 } 2849 finishProperties[4] = { 2850 tag: huks.HuksTag.HUKS_TAG_PURPOSE, 2851 value: 2852 huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT | 2853 huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT, 2854 } 2855 finishProperties[5] = { 2856 tag: huks.HuksTag.HUKS_TAG_DIGEST, 2857 value: huks.HuksKeyDigest.HUKS_DIGEST_NONE, 2858 } 2859 finishProperties[6] = { 2860 tag: huks.HuksTag.HUKS_TAG_KEY_ALIAS, 2861 value: StringToUint8Array(srcKeyAlias), 2862 } 2863 finishProperties[7] = { 2864 tag: huks.HuksTag.HUKS_TAG_PADDING, 2865 value: huks.HuksKeyPadding.HUKS_PADDING_NONE, 2866 } 2867 finishProperties[8] = { 2868 tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE, 2869 value: huks.HuksCipherMode.HUKS_MODE_ECB, 2870 } 2871 let finishOptions = { 2872 properties: finishProperties, 2873 inData: new Uint8Array(new Array()) 2874 } 2875 2876 /* Derive a key. */ 2877 await publicInitFunc(srcKeyAlias, huksOptions); 2878 2879 huksOptions.inData = StringToUint8Array(deriveHkdfInData); 2880 await publicUpdateFunc(handle, huksOptions); 2881 await publicFinishFunc(handle, finishOptions); 2882 2883 huksOptions.properties.splice(0, 1, { 2884 tag: huks.HuksTag.HUKS_TAG_ALGORITHM, 2885 value: huks.HuksKeyAlg.HUKS_ALG_AES, 2886 }); 2887 huksOptions.properties.splice(3, 1, { 2888 tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, 2889 value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_128, 2890 }); 2891 2892 await publicDeleteKeyFunc(srcKeyAlias, huksOptions); 2893} 2894 2895@Entry 2896@Component 2897struct Index { 2898 build() { 2899 Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { 2900 Button() { 2901 Text('testDerive') 2902 .fontSize(30) 2903 .fontWeight(FontWeight.Bold) 2904 }.type(ButtonType.Capsule) 2905 .margin({ 2906 top: 20 2907 }) 2908 .backgroundColor('#0D9FFB') 2909 .onClick(()=>{ 2910 testDerive(); 2911 }) 2912 } 2913 .width('100%') 2914 .height('100%') 2915 } 2916} 2917``` 2918 2919### Key MAC 2920 2921A message authentication code (MAC) is a hash-based value used for authenticating a message. It is used to check whether the message comes from the stated sender and has not been changed. 2922 2923The development procedure is as follows: 2924 29251. Generate a key. 29262. Generate a MAC. 2927 2928**Supported key types**: 2929 2930Only **HksInit()** has requirements on parameters in **paramSet**. The other Init-Update-Finish APIs have no requirements on **paramSet**. 2931 2932| HUKS_TAG_ALGORITHM | HUKS_TAG_KEY_SIZE | HUKS_TAG_PURPOSE | HUKS_TAG_DIGEST | HUKS_TAG_PADDING | HUKS_TAG_BLOCK_MODE | 2933| ------------ | ---------- | ------------------- | ------------------------------------------------------------ | ---------- | ---------- | 2934| HUKS_ALG_HMAC | Optional| HUKS_KEY_PURPOSE_MAC | HUKS_DIGEST_SHA1, HUKS_DIGEST_SHA224, HUKS_DIGEST_SHA256, HUKS_DIGEST_SHA384, HUKS_DIGEST_SHA512| Optional| Optional| 2935| HUKS_ALG_SM3 | Optional| HUKS_KEY_PURPOSE_MAC | HUKS_DIGEST_SM3 | Optional| Optional| 2936 2937> **NOTE**<br> 2938> 2939> The key alias cannot exceed 64 bytes. 2940 2941Before you get started, understand the following variables: 2942 2943| Parameter | Type | Mandatory| Description | 2944| ----------- | ----------- | ---- | -------------- | 2945| srcKeyAlias | string | Yes | Alias of the key generated.| 2946| huksOptions | HuksOptions | Yes | Key parameter set. | 2947 2948For details about the APIs, see [HUKS](../reference/apis/js-apis-huks.md). 2949 2950**Example** 2951 2952```ts 2953/*The mac() operation supports HMAC and SM3 keys. 2954 * 2955 * The following uses the Promise() operation of an SM3 256-bit key as an example. 2956 */ 2957import huks from '@ohos.security.huks'; 2958 2959function StringToUint8Array(str) { 2960 let arr = []; 2961 for (let i = 0, j = str.length; i < j; ++i) { 2962 arr.push(str.charCodeAt(i)); 2963 } 2964 return new Uint8Array(arr); 2965} 2966 2967async function publicGenKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) { 2968 console.info(`enter callback generateKeyItem`); 2969 try { 2970 await generateKeyItem(keyAlias, huksOptions) 2971 .then((data) => { 2972 console.info(`callback: generateKeyItem success, data = ${JSON.stringify(data)}`); 2973 }) 2974 .catch(error => { 2975 console.error(`callback: generateKeyItem failed, code: ${error.code}, msg: ${error.message}`); 2976 }); 2977 } catch (error) { 2978 console.error(`callback: generateKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`); 2979 } 2980} 2981 2982function generateKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) { 2983 return new Promise((resolve, reject) => { 2984 try { 2985 huks.generateKeyItem(keyAlias, huksOptions, function (error, data) { 2986 if (error) { 2987 reject(error); 2988 } else { 2989 resolve(data); 2990 } 2991 }); 2992 } catch (error) { 2993 throw(error); 2994 } 2995 }); 2996} 2997 2998async function publicInitFunc(keyAlias:string, huksOptions:huks.HuksOptions) { 2999 console.info(`enter callback doInit`); 3000 try { 3001 await initSession(keyAlias, huksOptions) 3002 .then ((data) => { 3003 console.info(`callback1: doInit success, data = ${JSON.stringify(data)}`); 3004 handle = data.handle; 3005 }) 3006 .catch((error) => { 3007 console.error(`callback1: doInit failed, code: ${error.code}, msg: ${error.message}`); 3008 }); 3009 } catch (error) { 3010 console.error(`callback: doInit input arg invalid, code: ${error.code}, msg: ${error.message}`); 3011 } 3012} 3013 3014function initSession(keyAlias:string, huksOptions:huks.HuksOptions) : Promise<huks.HuksSessionHandle> { 3015 return new Promise((resolve, reject) => { 3016 try { 3017 huks.initSession(keyAlias, huksOptions, function (error, data) { 3018 if (error) { 3019 reject(error); 3020 } else { 3021 resolve(data); 3022 } 3023 }); 3024 } catch (error) { 3025 throw(error); 3026 } 3027 }); 3028} 3029 3030async function publicUpdateFunc(handle:number, huksOptions:huks.HuksOptions) { 3031 console.info(`enter callback doUpdate`); 3032 try { 3033 await updateSession(handle, huksOptions) 3034 .then ((data) => { 3035 console.info(`callback: doUpdate success, data = ${JSON.stringify(data)}`); 3036 }) 3037 .catch(error => { 3038 console.error(`callback: doUpdate failed, code: ${error.code}, msg: ${error.message}`); 3039 }); 3040 } catch (error) { 3041 console.error(`callback: doUpdate input arg invalid, code: ${error.code}, msg: ${error.message}`); 3042 } 3043} 3044 3045function updateSession(handle:number, huksOptions:huks.HuksOptions) : Promise<huks.HuksReturnResult> { 3046 return new Promise((resolve, reject) => { 3047 try { 3048 huks.updateSession(handle, huksOptions, function (error, data) { 3049 if (error) { 3050 reject(error); 3051 } else { 3052 resolve(data); 3053 } 3054 }); 3055 } catch (error) { 3056 throw(error); 3057 } 3058 }); 3059} 3060 3061async function publicFinishFunc(handle:number, huksOptions:huks.HuksOptions) { 3062 console.info(`enter callback doFinish`); 3063 try { 3064 await finishSession(handle, huksOptions) 3065 .then ((data) => { 3066 console.info(`callback: doFinish success, data = ${JSON.stringify(data)}`); 3067 }) 3068 .catch(error => { 3069 console.error(`callback: doFinish failed, code: ${error.code}, msg: ${error.message}`); 3070 }); 3071 } catch (error) { 3072 console.error(`callback: doFinish input arg invalid, code: ${error.code}, msg: ${error.message}`); 3073 } 3074} 3075 3076function finishSession(handle:number, huksOptions:huks.HuksOptions) : Promise<huks.HuksReturnResult> { 3077 return new Promise((resolve, reject) => { 3078 try { 3079 huks.finishSession(handle, huksOptions, function (error, data) { 3080 if (error) { 3081 reject(error); 3082 } else { 3083 resolve(data); 3084 } 3085 }); 3086 } catch (error) { 3087 throw(error); 3088 } 3089 }); 3090} 3091 3092async function publicDeleteKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) { 3093 console.info(`enter callback deleteKeyItem`); 3094 try { 3095 await deleteKeyItem(keyAlias, huksOptions) 3096 .then ((data) => { 3097 console.info(`callback: deleteKeyItem key success, data = ${JSON.stringify(data)}`); 3098 }) 3099 .catch(error => { 3100 console.error(`callback: deleteKeyItem failed, code: ${error.code}, msg: ${error.message}`); 3101 }); 3102 } catch (error) { 3103 console.error(`callback: deleteKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`); 3104 } 3105} 3106 3107function deleteKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) { 3108 return new Promise((resolve, reject) => { 3109 try { 3110 huks.deleteKeyItem(keyAlias, huksOptions, function (error, data) { 3111 if (error) { 3112 reject(error); 3113 } else { 3114 resolve(data); 3115 } 3116 }); 3117 } catch (error) { 3118 throw(error); 3119 } 3120 }); 3121} 3122 3123let srcKeyAlias = "sm3KeyAlias"; 3124let hmacInData = 'sm3TestIndata'; 3125let handle; 3126 3127async function testMac() { 3128 /* Configure the parameters for generating the key. */ 3129 let properties = new Array(); 3130 properties[0] = { 3131 tag: huks.HuksTag.HUKS_TAG_ALGORITHM, 3132 value: huks.HuksKeyAlg.HUKS_ALG_SM3, 3133 } 3134 properties[1] = { 3135 tag: huks.HuksTag.HUKS_TAG_PURPOSE, 3136 value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_MAC, 3137 } 3138 properties[2] = { 3139 tag: huks.HuksTag.HUKS_TAG_DIGEST, 3140 value: huks.HuksKeyDigest.HUKS_DIGEST_SM3, 3141 } 3142 properties[3] = { 3143 tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, 3144 value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_256, 3145 } 3146 let huksOptions = { 3147 properties:properties, 3148 inData:new Uint8Array(new Array()) 3149 } 3150 3151 /* Generate a key. */ 3152 await publicGenKeyFunc(srcKeyAlias, huksOptions); 3153 3154 /* Modify the parameter set for init() and perform the mac operation. */ 3155 huksOptions.properties.splice(3, 3); 3156 await publicInitFunc(srcKeyAlias, huksOptions); 3157 huksOptions.inData = StringToUint8Array(hmacInData); 3158 await publicUpdateFunc(handle, huksOptions); 3159 huksOptions.inData = new Uint8Array(new Array()); 3160 await publicFinishFunc(handle, huksOptions); 3161 3162 huksOptions.properties.splice(1, 0, { 3163 tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, 3164 value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_256, 3165 }); 3166 await publicDeleteKeyFunc(srcKeyAlias, huksOptions); 3167} 3168 3169@Entry 3170@Component 3171struct Index { 3172 build() { 3173 Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { 3174 Button() { 3175 Text('testMac') 3176 .fontSize(30) 3177 .fontWeight(FontWeight.Bold) 3178 }.type(ButtonType.Capsule) 3179 .margin({ 3180 top: 20 3181 }) 3182 .backgroundColor('#0D9FFB') 3183 .onClick(()=>{ 3184 testMac(); 3185 }) 3186 } 3187 .width('100%') 3188 .height('100%') 3189 } 3190} 3191``` 3192 3193### AttestID 3194 3195After an application generates an asymmetric key, the certificate chain can be obtained through ID attestation. ID attestation supports the following device: brand, device, product, serial number, IMEI, MEID, manufacturer, model, SOC ID, and UDID. 3196 3197The application can also obtain the certificate chain through key attestation. 3198 3199ID attestation and key attestation are available only for devices in a trusted execution Environment (TEE). 3200 3201The development procedure is as follows: 3202 32031. Generate a certificate. 32042. Obtain certificate information. 3205 3206**Supported key types**: 3207 3208RSA512, RSA768, RSA1024, RSA2048, RSA3072, RSA4096, ECC224, ECC256, ECC384, ECC521, X25519 3209 3210> **NOTE**<br> 3211> 3212> The key alias cannot exceed 64 bytes. 3213 3214Before you get started, understand the following variables: 3215 3216| Parameter | Type | Mandatory| Description | 3217| -------- | ----------- | ---- | ------------------------------------ | 3218| keyAlias | string | Yes | Alias of the key. The certificate to be obtained stores the key.| 3219| options | HuksOptions | Yes | Parameters and data required for obtaining the certificate. | 3220 3221For details about the APIs, see [HUKS](../reference/apis/js-apis-huks.md). 3222 3223**Example** 3224 3225```ts 3226/* The following is an example of ID attestation. */ 3227import huks from '@ohos.security.huks'; 3228 3229function StringToUint8Array(str) { 3230 let arr = []; 3231 for (let i = 0, j = str.length; i < j; ++i) { 3232 arr.push(str.charCodeAt(i)); 3233 } 3234 return new Uint8Array(arr); 3235} 3236 3237async function publicGenKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) { 3238 console.info(`enter callback generateKeyItem`); 3239 try { 3240 await generateKeyItem(keyAlias, huksOptions) 3241 .then((data) => { 3242 console.info(`callback: generateKeyItem success, data = ${JSON.stringify(data)}`); 3243 }) 3244 .catch(error => { 3245 console.error(`callback: generateKeyItem failed, code: ${error.code}, msg: ${error.message}`); 3246 }); 3247 } catch (error) { 3248 console.error(`callback: generateKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`); 3249 } 3250} 3251 3252function generateKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) { 3253 return new Promise((resolve, reject) => { 3254 try { 3255 huks.generateKeyItem(keyAlias, huksOptions, function (error, data) { 3256 if (error) { 3257 reject(error); 3258 } else { 3259 resolve(data); 3260 } 3261 }); 3262 } catch (error) { 3263 throw(error); 3264 } 3265 }); 3266} 3267 3268async function publicAttestKey(keyAlias:string, huksOptions:huks.HuksOptions) { 3269 console.info(`enter callback attestKeyItem`); 3270 try { 3271 await attestKeyItem(keyAlias, huksOptions) 3272 .then ((data) => { 3273 console.info(`callback: attestKeyItem success, data = ${JSON.stringify(data)}`); 3274 }) 3275 .catch(error => { 3276 console.error(`callback: attestKeyItem failed, code: ${error.code}, msg: ${error.message}`); 3277 }); 3278 } catch (error) { 3279 console.error(`callback: attestKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`); 3280 } 3281} 3282 3283function attestKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) : Promise<huks.HuksReturnResult>{ 3284 return new Promise((resolve, reject) => { 3285 try { 3286 huks.attestKeyItem(keyAlias, huksOptions, function (error, data) { 3287 if (error) { 3288 reject(error); 3289 } else { 3290 resolve(data); 3291 } 3292 }); 3293 } catch (error) { 3294 throw(error); 3295 } 3296 }); 3297} 3298 3299async function publicDeleteKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) { 3300 console.info(`enter callback deleteKeyItem`); 3301 try { 3302 await deleteKeyItem(keyAlias, huksOptions) 3303 .then ((data) => { 3304 console.info(`callback: deleteKeyItem key success, data = ${JSON.stringify(data)}`); 3305 }) 3306 .catch(error => { 3307 console.error(`callback: deleteKeyItem failed, code: ${error.code}, msg: ${error.message}`); 3308 }); 3309 } catch (error) { 3310 console.error(`callback: deleteKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`); 3311 } 3312} 3313 3314function deleteKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) { 3315 return new Promise((resolve, reject) => { 3316 try { 3317 huks.deleteKeyItem(keyAlias, huksOptions, function (error, data) { 3318 if (error) { 3319 reject(error); 3320 } else { 3321 resolve(data); 3322 } 3323 }); 3324 } catch (error) { 3325 throw(error); 3326 } 3327 }); 3328} 3329 3330let securityLevel = StringToUint8Array('sec_level'); 3331let challenge = StringToUint8Array('challenge_data'); 3332let versionInfo = StringToUint8Array('version_info'); 3333let udid = StringToUint8Array('udid'); 3334let serial = StringToUint8Array('serial'); 3335let deviceId = StringToUint8Array('device_id'); 3336let idAliasString = "id attest"; 3337 3338async function testAttestId() { 3339 let aliasString = idAliasString; 3340 let aliasUint8 = StringToUint8Array(aliasString); 3341 3342 /* Configure parameters and generate a key. */ 3343 let properties = new Array(); 3344 properties[0] = { 3345 tag: huks.HuksTag.HUKS_TAG_ALGORITHM, 3346 value: huks.HuksKeyAlg.HUKS_ALG_RSA 3347 }; 3348 properties[1] = { 3349 tag: huks.HuksTag.HUKS_TAG_KEY_STORAGE_FLAG, 3350 value: huks.HuksKeyStorageType.HUKS_STORAGE_PERSISTENT 3351 }; 3352 properties[2] = { 3353 tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, 3354 value: huks.HuksKeySize.HUKS_RSA_KEY_SIZE_2048 3355 }; 3356 properties[3] = { 3357 tag: huks.HuksTag.HUKS_TAG_PURPOSE, 3358 value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_VERIFY 3359 }; 3360 properties[4] = { 3361 tag: huks.HuksTag.HUKS_TAG_DIGEST, 3362 value: huks.HuksKeyDigest.HUKS_DIGEST_SHA256 3363 }; 3364 properties[5] = { 3365 tag: huks.HuksTag.HUKS_TAG_PADDING, 3366 value: huks.HuksKeyPadding.HUKS_PADDING_PSS 3367 }; 3368 properties[6] = { 3369 tag: huks.HuksTag.HUKS_TAG_KEY_GENERATE_TYPE, 3370 value: huks.HuksKeyGenerateType.HUKS_KEY_GENERATE_TYPE_DEFAULT 3371 }; 3372 properties[7] = { 3373 tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE, 3374 value: huks.HuksCipherMode.HUKS_MODE_ECB 3375 }; 3376 let options = { 3377 properties: properties 3378 }; 3379 await publicGenKeyFunc(aliasString, options); 3380 3381 /* Configure the certificate parameter set. */ 3382 let attestProperties = new Array(); 3383 attestProperties[0] = { 3384 tag: huks.HuksTag.HUKS_TAG_ATTESTATION_ID_SEC_LEVEL_INFO, 3385 value: securityLevel 3386 }; 3387 attestProperties[1] = { 3388 tag: huks.HuksTag.HUKS_TAG_ATTESTATION_CHALLENGE, 3389 value: challenge 3390 }; 3391 attestProperties[2] = { 3392 tag: huks.HuksTag.HUKS_TAG_ATTESTATION_ID_VERSION_INFO, 3393 value: versionInfo 3394 }; 3395 attestProperties[3] = { 3396 tag: huks.HuksTag.HUKS_TAG_ATTESTATION_ID_ALIAS, 3397 value: aliasUint8 3398 }; 3399 attestProperties[4] = { 3400 tag: huks.HuksTag.HUKS_TAG_ATTESTATION_ID_UDID, 3401 value: udid 3402 }; 3403 attestProperties[5] = { 3404 tag: huks.HuksTag.HUKS_TAG_ATTESTATION_ID_SERIAL, 3405 value: serial 3406 }; 3407 attestProperties[6] = { 3408 tag: huks.HuksTag.HUKS_TAG_ATTESTATION_ID_DEVICE, 3409 value: deviceId 3410 }; 3411 let huksOptions = { 3412 properties: attestProperties 3413 }; 3414 3415 await publicAttestKey(aliasString, huksOptions); 3416 3417 await publicDeleteKeyFunc(aliasString, options); 3418} 3419 3420@Entry 3421@Component 3422struct Index { 3423 build() { 3424 Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { 3425 Button() { 3426 Text('testAttestId') 3427 .fontSize(30) 3428 .fontWeight(FontWeight.Bold) 3429 }.type(ButtonType.Capsule) 3430 .margin({ 3431 top: 20 3432 }) 3433 .backgroundColor('#0D9FFB') 3434 .onClick(()=>{ 3435 testAttestId(); 3436 }) 3437 } 3438 .width('100%') 3439 .height('100%') 3440 } 3441} 3442``` 3443 3444### AttestKey 3445 3446After an application generates an asymmetric key, the certificate chain can be obtained by key attestation. You can also use ID attestation to obtain the certificate chain. The public certificate contains information such as the device ID. 3447 3448ID attestation and key attestation are available only for devices in a trusted execution Environment (TEE). 3449 3450The development procedure is as follows: 3451 34521. Generate a certificate. 34532. Obtain certificate information. 3454 3455**Supported key types**: 3456 3457RSA512, RSA768, RSA1024, RSA2048, RSA3072, RSA4096, ECC224, ECC256, ECC384, ECC521, X25519 3458 3459> **NOTE**<br> 3460> 3461> The key alias cannot exceed 64 bytes. 3462 3463Before you get started, understand the following variables: 3464 3465| Parameter | Type | Mandatory| Description | 3466| -------- | ----------- | ---- | ------------------------------------ | 3467| keyAlias | string | Yes | Alias of the key. The certificate to be obtained stores the key.| 3468| options | HuksOptions | Yes | Parameters and data required for obtaining the certificate. | 3469 3470For details about the APIs, see [HUKS](../reference/apis/js-apis-huks.md). 3471 3472**Example** 3473 3474```ts 3475/* The following is an example of AttestKey. */ 3476import huks from '@ohos.security.huks'; 3477 3478function StringToUint8Array(str) { 3479 let arr = []; 3480 for (let i = 0, j = str.length; i < j; ++i) { 3481 arr.push(str.charCodeAt(i)); 3482 } 3483 return new Uint8Array(arr); 3484} 3485 3486async function publicGenKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) { 3487 console.info(`enter callback generateKeyItem`); 3488 try { 3489 await generateKeyItem(keyAlias, huksOptions) 3490 .then((data) => { 3491 console.info(`callback: generateKeyItem success, data = ${JSON.stringify(data)}`); 3492 }) 3493 .catch(error => { 3494 console.error(`callback: generateKeyItem failed, code: ${error.code}, msg: ${error.message}`); 3495 }); 3496 } catch (error) { 3497 console.error(`callback: generateKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`); 3498 } 3499} 3500 3501function generateKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) { 3502 return new Promise((resolve, reject) => { 3503 try { 3504 huks.generateKeyItem(keyAlias, huksOptions, function (error, data) { 3505 if (error) { 3506 reject(error); 3507 } else { 3508 resolve(data); 3509 } 3510 }); 3511 } catch (error) { 3512 throw(error); 3513 } 3514 }); 3515} 3516 3517async function publicAttestKey(keyAlias:string, huksOptions:huks.HuksOptions) { 3518 console.info(`enter callback attestKeyItem`); 3519 try { 3520 await attestKeyItem(keyAlias, huksOptions) 3521 .then ((data) => { 3522 console.info(`callback: attestKeyItem success, data = ${JSON.stringify(data)}`); 3523 }) 3524 .catch(error => { 3525 console.error(`callback: attestKeyItem failed, code: ${error.code}, msg: ${error.message}`); 3526 }); 3527 } catch (error) { 3528 console.error(`callback: attestKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`); 3529 } 3530} 3531 3532function attestKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) : Promise<huks.HuksReturnResult>{ 3533 return new Promise((resolve, reject) => { 3534 try { 3535 huks.attestKeyItem(keyAlias, huksOptions, function (error, data) { 3536 if (error) { 3537 reject(error); 3538 } else { 3539 resolve(data); 3540 } 3541 }); 3542 } catch (error) { 3543 throw(error); 3544 } 3545 }); 3546} 3547 3548async function publicDeleteKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) { 3549 console.info(`enter callback deleteKeyItem`); 3550 try { 3551 await deleteKeyItem(keyAlias, huksOptions) 3552 .then ((data) => { 3553 console.info(`callback: deleteKeyItem key success, data = ${JSON.stringify(data)}`); 3554 }) 3555 .catch(error => { 3556 console.error(`callback: deleteKeyItem failed, code: ${error.code}, msg: ${error.message}`); 3557 }); 3558 } catch (error) { 3559 console.error(`callback: deleteKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`); 3560 } 3561} 3562 3563function deleteKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) { 3564 return new Promise((resolve, reject) => { 3565 try { 3566 huks.deleteKeyItem(keyAlias, huksOptions, function (error, data) { 3567 if (error) { 3568 reject(error); 3569 } else { 3570 resolve(data); 3571 } 3572 }); 3573 } catch (error) { 3574 throw(error); 3575 } 3576 }); 3577} 3578 3579let securityLevel = StringToUint8Array('sec_level'); 3580let challenge = StringToUint8Array('challenge_data'); 3581let versionInfo = StringToUint8Array('version_info'); 3582let keyAliasString = "key attest"; 3583 3584async function testAttestKey() { 3585 let aliasString = keyAliasString; 3586 let aliasUint8 = StringToUint8Array(aliasString); 3587 3588 let properties = new Array(); 3589 properties[0] = { 3590 tag: huks.HuksTag.HUKS_TAG_ALGORITHM, 3591 value: huks.HuksKeyAlg.HUKS_ALG_RSA 3592 }; 3593 properties[1] = { 3594 tag: huks.HuksTag.HUKS_TAG_KEY_STORAGE_FLAG, 3595 value: huks.HuksKeyStorageType.HUKS_STORAGE_PERSISTENT 3596 }; 3597 properties[2] = { 3598 tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, 3599 value: huks.HuksKeySize.HUKS_RSA_KEY_SIZE_2048 3600 }; 3601 properties[3] = { 3602 tag: huks.HuksTag.HUKS_TAG_PURPOSE, 3603 value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_VERIFY 3604 }; 3605 properties[4] = { 3606 tag: huks.HuksTag.HUKS_TAG_DIGEST, 3607 value: huks.HuksKeyDigest.HUKS_DIGEST_SHA256 3608 }; 3609 properties[5] = { 3610 tag: huks.HuksTag.HUKS_TAG_PADDING, 3611 value: huks.HuksKeyPadding.HUKS_PADDING_PSS 3612 }; 3613 properties[6] = { 3614 tag: huks.HuksTag.HUKS_TAG_KEY_GENERATE_TYPE, 3615 value: huks.HuksKeyGenerateType.HUKS_KEY_GENERATE_TYPE_DEFAULT 3616 }; 3617 properties[7] = { 3618 tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE, 3619 value: huks.HuksCipherMode.HUKS_MODE_ECB 3620 }; 3621 let options = { 3622 properties: properties 3623 }; 3624 await publicGenKeyFunc(aliasString, options); 3625 3626 /* Configure the certificate parameter set. */ 3627 let attestProperties = new Array(); 3628 attestProperties[0] = { 3629 tag: huks.HuksTag.HUKS_TAG_ATTESTATION_ID_SEC_LEVEL_INFO, 3630 value: securityLevel 3631 }; 3632 attestProperties[1] = { 3633 tag: huks.HuksTag.HUKS_TAG_ATTESTATION_CHALLENGE, 3634 value: challenge 3635 }; 3636 attestProperties[2] = { 3637 tag: huks.HuksTag.HUKS_TAG_ATTESTATION_ID_VERSION_INFO, 3638 value: versionInfo 3639 }; 3640 attestProperties[3] = { 3641 tag: huks.HuksTag.HUKS_TAG_ATTESTATION_ID_ALIAS, 3642 value: aliasUint8 3643 }; 3644 let huksOptions = { 3645 properties: attestProperties 3646 }; 3647 3648 await publicAttestKey(aliasString, huksOptions); 3649 3650 await publicDeleteKeyFunc(aliasString, options); 3651} 3652 3653@Entry 3654@Component 3655struct Index { 3656 build() { 3657 Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { 3658 Button() { 3659 Text('testAttestKey') 3660 .fontSize(30) 3661 .fontWeight(FontWeight.Bold) 3662 }.type(ButtonType.Capsule) 3663 .margin({ 3664 top: 20 3665 }) 3666 .backgroundColor('#0D9FFB') 3667 .onClick(()=>{ 3668 testAttestKey(); 3669 }) 3670 } 3671 .width('100%') 3672 .height('100%') 3673 } 3674} 3675``` 3676