1# Key Agreement (ArkTS) 2 3 4This topic walks you through on how to agree on a 256-bit X25519 key that is used only in HUKS. For details about the scenarios and supported algorithms, see [Supported Algorithms](huks-key-generation-overview.md#supported-algorithms). 5 6 7## How to Develop 8 9**Key Generation** 10 11Generate an asymmetric key for device A and device B each. For details, see [Key Generation](huks-key-generation-overview.md) or [Key Import](huks-key-import-overview.md). 12 13When generating a key, you can set **HUKS_TAG_DERIVED_AGREED_KEY_STORAGE_FLAG** (optional) to specify how the shared secret generated from this key through key agreement is managed. 14 15- If this tag is set to **HUKS_STORAGE_ONLY_USED_IN_HUKS**, the shared secret is managed by HUKS. That is, the shared secret is always in a secure environment throughout its lifecycle. 16 17- If this tag is set to **HUKS_STORAGE_KEY_EXPORT_ALLOWED**, the shared secret generated will be returned to the caller for management. That is, the service side ensures the key security. 18 19- If this tag is not set, the shared secret generated can be either managed by HUKS or returned to the caller for management. The key protection mode can be set in the subsequent key agreement on the service side. 20 21**Key Export** 22 23Export the public key of the asymmetric key pair of device A and device B. For details, see [Key Export](huks-export-key-arkts.md). 24 25**Key Agreement** 26 27Perform key agreement using the public key of the peer device and private key of the local device (that is, public key of device B and private key of device A for device A, and public key of device A and private key of device B for device B) to produce a shared secret. 28 29During key agreement, you can set **HUKS_TAG_DERIVED_AGREED_KEY_STORAGE_FLAG** (optional) to specify how the shared secret generated is managed. 30 31| Key Generation| Key Agreement| Specifications| 32| -------- | -------- | -------- | 33| HUKS_STORAGE_ONLY_USED_IN_HUKS | HUKS_STORAGE_ONLY_USED_IN_HUKS | The key is managed by HUKS.| 34| HUKS_STORAGE_KEY_EXPORT_ALLOWED | HUKS_STORAGE_KEY_EXPORT_ALLOWED | The key is returned to the caller for management.| 35| The tag is not set.| HUKS_STORAGE_ONLY_USED_IN_HUKS | The key is managed by HUKS.| 36| The tag is not set.| HUKS_STORAGE_KEY_EXPORT_ALLOWED | The key is returned to the caller for management.| 37| The tag is not set.| The tag is not set.| The key is returned to the caller for management.| 38 39>**NOTE**<br>The tag value set in key agreement should not conflict with the tag value set in key generation. The above table lists only valid settings. 40 41**Key Deletion** 42 43Delete the keys from device A and device B when the keys are not required. For details, see [Deleting a Key](huks-delete-key-arkts.md). 44 45 46Example: Perform X25519 key agreement. 47```ts 48/* 49* Agree on a 256-bit X25519 key using promise-based APIs. 50*/ 51import { huks } from '@kit.UniversalKeystoreKit'; 52 53/* 54* Set the key alias and encapsulate the key property set. 55*/ 56let srcKeyAliasFirst = "AgreeX25519KeyFirstAlias"; 57let srcKeyAliasSecond = "AgreeX25519KeySecondAlias"; 58let agreeX25519InData = 'AgreeX25519TestIndata'; 59let finishOutData: Uint8Array; 60let handle: number; 61let exportKey: Uint8Array; 62let exportKeyFirst: Uint8Array; 63let exportKeySecond: Uint8Array; 64/* Set the parameter set used for generating the key. */ 65let properties: Array<huks.HuksParam> = [{ 66 tag: huks.HuksTag.HUKS_TAG_ALGORITHM, 67 value: huks.HuksKeyAlg.HUKS_ALG_X25519, 68}, { 69 tag: huks.HuksTag.HUKS_TAG_PURPOSE, 70 value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_AGREE, 71}, { 72 tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, 73 value: huks.HuksKeySize.HUKS_CURVE25519_KEY_SIZE_256, 74}, { 75 tag: huks.HuksTag.HUKS_TAG_DIGEST, 76 value: huks.HuksKeyDigest.HUKS_DIGEST_NONE, 77}, { 78 tag: huks.HuksTag.HUKS_TAG_PADDING, 79 value: huks.HuksKeyPadding.HUKS_PADDING_NONE, 80}, { 81 tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE, 82 value: huks.HuksCipherMode.HUKS_MODE_CBC, 83}, { 84 tag: huks.HuksTag.HUKS_TAG_DERIVED_AGREED_KEY_STORAGE_FLAG, 85 value: huks.HuksKeyStorageType.HUKS_STORAGE_ONLY_USED_IN_HUKS, 86}]; 87let HuksOptions: huks.HuksOptions = { 88 properties: properties, 89 inData: new Uint8Array(new Array()) 90} 91/* Set the parameter set for the first key agreement. */ 92const finishProperties: Array<huks.HuksParam> = [{ 93 tag: huks.HuksTag.HUKS_TAG_DERIVED_AGREED_KEY_STORAGE_FLAG, 94 value: huks.HuksKeyStorageType.HUKS_STORAGE_ONLY_USED_IN_HUKS, 95}, { 96 tag: huks.HuksTag.HUKS_TAG_IS_KEY_ALIAS, 97 value: true 98}, { 99 tag: huks.HuksTag.HUKS_TAG_ALGORITHM, 100 value: huks.HuksKeyAlg.HUKS_ALG_AES, 101}, { 102 tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, 103 value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_256, 104}, { 105 tag: huks.HuksTag.HUKS_TAG_PURPOSE, 106 value: 107 huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT | 108 huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT, 109}, { 110 tag: huks.HuksTag.HUKS_TAG_DIGEST, 111 value: huks.HuksKeyDigest.HUKS_DIGEST_NONE, 112}, { 113 tag: huks.HuksTag.HUKS_TAG_PADDING, 114 value: huks.HuksKeyPadding.HUKS_PADDING_NONE, 115}, { 116 tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE, 117 value: huks.HuksCipherMode.HUKS_MODE_ECB, 118}]; 119let finishOptionsFirst: huks.HuksOptions = { 120 properties: [ 121 ...finishProperties, { 122 tag: huks.HuksTag.HUKS_TAG_KEY_ALIAS, 123 value: StringToUint8Array(srcKeyAliasFirst + 'final'), 124 }], 125 inData: StringToUint8Array(agreeX25519InData) 126} 127/* Set the parameter set for the second key agreement. */ 128let finishOptionsSecond: huks.HuksOptions = { 129 properties: [ 130 ...finishProperties, { 131 tag: huks.HuksTag.HUKS_TAG_KEY_ALIAS, 132 value: StringToUint8Array(srcKeyAliasSecond + 'final'), 133 }], 134 inData: StringToUint8Array(agreeX25519InData) 135} 136 137function StringToUint8Array(str: string) { 138 let arr: number[] = new Array(); 139 for (let i = 0, j = str.length; i < j; ++i) { 140 arr.push(str.charCodeAt(i)); 141 } 142 return new Uint8Array(arr); 143} 144 145class throwObject { 146 isThrow: boolean = false 147} 148 149/* Generate a key. */ 150function generateKeyItem(keyAlias: string, huksOptions: huks.HuksOptions, throwObject: throwObject) { 151 return new Promise<void>((resolve, reject) => { 152 try { 153 huks.generateKeyItem(keyAlias, huksOptions, (error, data) => { 154 if (error) { 155 reject(error); 156 } else { 157 resolve(data); 158 } 159 }); 160 } catch (error) { 161 throwObject.isThrow = true; 162 throw (error as Error); 163 } 164 }); 165} 166 167/* Call generateKeyItem to generate a key. */ 168async function publicGenKeyFunc(keyAlias: string, huksOptions: huks.HuksOptions) { 169 console.info(`enter promise generateKeyItem`); 170 let throwObject: throwObject = { isThrow: false }; 171 try { 172 await generateKeyItem(keyAlias, huksOptions, throwObject) 173 .then((data) => { 174 console.info(`promise: generateKeyItem success, data = ${JSON.stringify(data)}`); 175 }) 176 .catch((error: Error) => { 177 if (throwObject.isThrow) { 178 throw (error as Error); 179 } else { 180 console.error(`promise: generateKeyItem failed, ${JSON.stringify(error)}`); 181 } 182 }); 183 } catch (error) { 184 console.error(`promise: generateKeyItem input arg invalid, ${JSON.stringify(error)}`); 185 } 186} 187 188/* Initializes a key session, which returns a session handle (mandatory) and a challenge (optional). */ 189function initSession(keyAlias: string, huksOptions: huks.HuksOptions, throwObject: throwObject) { 190 return new Promise<huks.HuksSessionHandle>((resolve, reject) => { 191 try { 192 huks.initSession(keyAlias, huksOptions, (error, data) => { 193 if (error) { 194 reject(error); 195 } else { 196 resolve(data); 197 } 198 }); 199 } catch (error) { 200 throwObject.isThrow = true; 201 throw (error as Error); 202 } 203 }); 204} 205 206/* Call initSession. A session handle is returned. */ 207async function publicInitFunc(keyAlias: string, huksOptions: huks.HuksOptions) { 208 console.info(`enter promise doInit`); 209 let throwObject: throwObject = { isThrow: false }; 210 try { 211 await initSession(keyAlias, huksOptions, throwObject) 212 .then((data) => { 213 console.info(`promise: doInit success, data = ${JSON.stringify(data)}`); 214 handle = data.handle; 215 }) 216 .catch((error: Error) => { 217 if (throwObject.isThrow) { 218 throw (error as Error); 219 } else { 220 console.error(`promise: doInit failed, ${JSON.stringify(error)}`); 221 } 222 }); 223 } catch (error) { 224 console.error(`promise: doInit input arg invalid, ${JSON.stringify(error)}`); 225 } 226} 227 228/* Call updateSession multiple times to process data by segment and output the processed data. */ 229function updateSession(handle: number, huksOptions: huks.HuksOptions, throwObject: throwObject) { 230 return new Promise<huks.HuksReturnResult>((resolve, reject) => { 231 try { 232 huks.updateSession(handle, huksOptions, (error, data) => { 233 if (error) { 234 reject(error); 235 } else { 236 resolve(data); 237 } 238 }); 239 } catch (error) { 240 throwObject.isThrow = true; 241 throw (error as Error); 242 } 243 }); 244} 245 246/* Call updateSession to perform key agreement. */ 247async function publicUpdateFunc(handle: number, huksOptions: huks.HuksOptions) { 248 console.info(`enter promise doUpdate`); 249 let throwObject: throwObject = { isThrow: false }; 250 try { 251 await updateSession(handle, huksOptions, throwObject) 252 .then((data) => { 253 console.info(`promise: doUpdate success, data = ${JSON.stringify(data)}`); 254 }) 255 .catch((error: Error) => { 256 if (throwObject.isThrow) { 257 throw (error as Error); 258 } else { 259 console.error(`promise: doUpdate failed, ${JSON.stringify(error)}`); 260 } 261 }); 262 } catch (error) { 263 console.error(`promise: doUpdate input arg invalid, ${JSON.stringify(error)}`); 264 } 265} 266 267/* Finish the key session to output the shared secret key. */ 268function finishSession(handle: number, huksOptions: huks.HuksOptions, throwObject: throwObject) { 269 return new Promise<huks.HuksReturnResult>((resolve, reject) => { 270 try { 271 huks.finishSession(handle, huksOptions, (error, data) => { 272 if (error) { 273 reject(error); 274 } else { 275 resolve(data); 276 } 277 }); 278 } catch (error) { 279 throwObject.isThrow = true; 280 throw (error as Error); 281 } 282 }); 283} 284 285/* Call finishSession to finish the operation. */ 286async function publicFinishFunc(handle: number, huksOptions: huks.HuksOptions) { 287 console.info(`enter promise doFinish`); 288 let throwObject: throwObject = { isThrow: false }; 289 try { 290 await finishSession(handle, huksOptions, throwObject) 291 .then((data) => { 292 finishOutData = data.outData as Uint8Array; 293 console.info(`promise: doFinish success, data = ${JSON.stringify(data)}`); 294 }) 295 .catch((error: Error) => { 296 if (throwObject.isThrow) { 297 throw (error as Error); 298 } else { 299 console.error(`promise: doFinish failed, ${JSON.stringify(error)}`); 300 } 301 }); 302 } catch (error) { 303 console.error(`promise: doFinish input arg invalid, ${JSON.stringify(error)}`); 304 } 305} 306 307/* Export a key. */ 308function exportKeyItem(keyAlias: string, huksOptions: huks.HuksOptions, throwObject: throwObject) { 309 return new Promise<huks.HuksReturnResult>((resolve, reject) => { 310 try { 311 huks.exportKeyItem(keyAlias, huksOptions, (error, data) => { 312 if (error) { 313 reject(error); 314 } else { 315 resolve(data); 316 } 317 }); 318 } catch (error) { 319 throwObject.isThrow = true; 320 throw (error as Error); 321 } 322 }); 323} 324 325/* Call exportKeyItem to export the public key. */ 326async function publicExportKeyFunc(keyAlias: string, huksOptions: huks.HuksOptions) { 327 console.info(`enter promise export`); 328 let throwObject: throwObject = { isThrow: false }; 329 try { 330 await exportKeyItem(keyAlias, huksOptions, throwObject) 331 .then((data) => { 332 console.info(`promise: exportKeyItem success, data = ${JSON.stringify(data)}`); 333 exportKey = data.outData as Uint8Array; 334 }) 335 .catch((error: Error) => { 336 if (throwObject.isThrow) { 337 throw (error as Error); 338 } else { 339 console.error(`promise: exportKeyItem failed, ${JSON.stringify(error)}`); 340 } 341 }); 342 } catch (error) { 343 console.error(`promise: exportKeyItem input arg invalid, ${JSON.stringify(error)}`); 344 } 345} 346 347/* Delete the keys. */ 348function deleteKeyItem(keyAlias: string, huksOptions: huks.HuksOptions, throwObject: throwObject) { 349 return new Promise<void>((resolve, reject) => { 350 try { 351 huks.deleteKeyItem(keyAlias, huksOptions, (error, data) => { 352 if (error) { 353 reject(error); 354 } else { 355 resolve(data); 356 } 357 }); 358 } catch (error) { 359 throwObject.isThrow = true; 360 throw (error as Error); 361 } 362 }); 363} 364 365/* Call deleteKeyItem to delete a key. */ 366async function publicDeleteKeyFunc(keyAlias: string, huksOptions: huks.HuksOptions) { 367 console.info(`enter promise deleteKeyItem`); 368 let throwObject: throwObject = { isThrow: false }; 369 try { 370 await deleteKeyItem(keyAlias, huksOptions, throwObject) 371 .then((data) => { 372 console.info(`promise: deleteKeyItem key success, data = ${JSON.stringify(data)}`); 373 }) 374 .catch((error: Error) => { 375 if (throwObject.isThrow) { 376 throw (error as Error); 377 } else { 378 console.error(`promise: deleteKeyItem failed, ${JSON.stringify(error)}`); 379 } 380 }); 381 } catch (error) { 382 console.error(`promise: deleteKeyItem input arg invalid, ${JSON.stringify(error)}`); 383 } 384} 385 386async function testAgree() { 387 /* 1. Set the key alias srcKeyAliasFirst for device A and srcKeyAliasSecond for device B, and parameters for generating the key pairs. */ 388 /* 2. Generate an asymmetric key pair for device A. */ 389 await publicGenKeyFunc(srcKeyAliasFirst, HuksOptions); 390 /* 3. Generate an asymmetric key pair for device B. */ 391 await publicGenKeyFunc(srcKeyAliasSecond, HuksOptions); 392 /* 4. Export the public keys of the key pairs of device A and device B. */ 393 await publicExportKeyFunc(srcKeyAliasFirst, HuksOptions); 394 exportKeyFirst = exportKey; 395 await publicExportKeyFunc(srcKeyAliasSecond, HuksOptions); 396 exportKeySecond = exportKey; 397 /* 5. Perform key agreement (Init-Update-Finish) for device A. */ 398 await publicInitFunc(srcKeyAliasFirst, HuksOptions); 399 HuksOptions.inData = exportKeySecond; 400 await publicUpdateFunc(handle, HuksOptions); 401 await publicFinishFunc(handle, finishOptionsFirst); 402 /* 5. Perform key agreement (Init-Update-Finish) for device B. */ 403 await publicInitFunc(srcKeyAliasSecond, HuksOptions); 404 HuksOptions.inData = exportKeyFirst; 405 await publicUpdateFunc(handle, HuksOptions); 406 await publicFinishFunc(handle, finishOptionsSecond); 407 /* 6. Delete keys from device A and device B. */ 408 await publicDeleteKeyFunc(srcKeyAliasFirst, HuksOptions); 409 await publicDeleteKeyFunc(srcKeyAliasSecond, HuksOptions); 410} 411``` 412 413Example: Perform DH key agreement. 414 415```ts 416/* 417 * Agree on a DH key using promise-based APIs. 418 */ 419import { huks } from '@kit.UniversalKeystoreKit' 420 421function StringToUint8Array(str: string) { 422 let arr: number[] = [] 423 for (let i = 0, j = str.length; i < j; ++i) { 424 arr.push(str.charCodeAt(i)) 425 } 426 return new Uint8Array(arr) 427} 428 429function Uint8ArrayToBigInt(arr: Uint8Array): bigint { 430 let i = 0 431 const byteMax: bigint = BigInt('0x100') 432 let result: bigint = BigInt('0') 433 while (i < arr.length) { 434 result = result * byteMax 435 result = result + BigInt(arr[i]) 436 i += 1 437 } 438 return result 439} 440 441const dhAgree: Array<huks.HuksParam> = [{ 442 tag: huks.HuksTag.HUKS_TAG_ALGORITHM, 443 value: huks.HuksKeyAlg.HUKS_ALG_DH, 444}, { 445 tag: huks.HuksTag.HUKS_TAG_PURPOSE, 446 value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_AGREE, 447}] 448const dh2048Agree: Array<huks.HuksParam> = [ 449 ...dhAgree, { 450 tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, 451 value: huks.HuksKeySize.HUKS_DH_KEY_SIZE_2048, 452}] 453const dhGenOptions: huks.HuksOptions = { 454 properties: dh2048Agree, 455 inData: new Uint8Array([]) 456} 457const emptyOptions: huks.HuksOptions = { 458 properties: [], 459 inData: new Uint8Array([]) 460} 461 462async function HuksDhAgreeExportKey(keyAlias: string, 463 peerPubKey: huks.HuksReturnResult): Promise<huks.HuksReturnResult> { 464 const initHandle = await huks.initSession(keyAlias, dhGenOptions) 465 const dhAgreeUpdateBobPubKey: huks.HuksOptions = { 466 properties: [ 467 ...dh2048Agree, { 468 tag: huks.HuksTag.HUKS_TAG_DERIVED_AGREED_KEY_STORAGE_FLAG, 469 value: huks.HuksKeyStorageType.HUKS_STORAGE_KEY_EXPORT_ALLOWED, 470 }], 471 inData: peerPubKey.outData 472 } 473 await huks.updateSession(initHandle.handle, dhAgreeUpdateBobPubKey) 474 return await huks.finishSession(initHandle.handle, emptyOptions) 475} 476 477async function HuksDhAgreeExportTest( 478 aliasA: string, aliasB: string, 479 pubKeyA: huks.HuksReturnResult, pubKeyB: huks.HuksReturnResult) { 480 481 const agreedKeyFromAlice = await HuksDhAgreeExportKey(aliasA, pubKeyB) 482 console.info(`ok! agreedKeyFromAlice export is 0x${Uint8ArrayToBigInt(agreedKeyFromAlice.outData).toString(16)}`) 483 484 const agreedKeyFromBob = await HuksDhAgreeExportKey(aliasB, pubKeyA) 485 console.info(`ok! agreedKeyFromBob export is 0x${Uint8ArrayToBigInt(agreedKeyFromBob.outData).toString(16)}`) 486} 487 488async function HuksDhAgreeInHuks(keyAlias: string, peerPubKey: huks.HuksReturnResult, 489 aliasAgreedKey: string): Promise<huks.HuksReturnResult> { 490 const onlyUsedInHuks: Array<huks.HuksParam> = [{ 491 tag: huks.HuksTag.HUKS_TAG_KEY_STORAGE_FLAG, 492 value: huks.HuksKeyStorageType.HUKS_STORAGE_ONLY_USED_IN_HUKS, 493 }, { 494 tag: huks.HuksTag.HUKS_TAG_DERIVED_AGREED_KEY_STORAGE_FLAG, 495 value: huks.HuksKeyStorageType.HUKS_STORAGE_ONLY_USED_IN_HUKS, 496 }] 497 const dhAgreeInit: huks.HuksOptions = { 498 properties: [ 499 ...dhAgree, 500 { tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_256, }, 501 ...onlyUsedInHuks], 502 inData: new Uint8Array([]) 503 } 504 const dhAgreeFinishParams: Array<huks.HuksParam> = [ 505 ...onlyUsedInHuks, 506 { tag: huks.HuksTag.HUKS_TAG_IS_KEY_ALIAS, value: true }, 507 { tag: huks.HuksTag.HUKS_TAG_ALGORITHM, value: huks.HuksKeyAlg.HUKS_ALG_AES }, 508 { tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_256 }, 509 { 510 tag: huks.HuksTag.HUKS_TAG_PURPOSE, 511 value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT | huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT 512 }] 513 514 const handle = await huks.initSession(keyAlias, dhAgreeInit) 515 const dhAgreeUpdatePubKey: huks.HuksOptions = { 516 properties: [...dhAgree, ...onlyUsedInHuks], 517 inData: peerPubKey.outData 518 } 519 await huks.updateSession(handle.handle, dhAgreeUpdatePubKey) 520 const dhAgreeAliceFinnish: huks.HuksOptions = { 521 properties: [...dhAgreeFinishParams, { 522 tag: huks.HuksTag.HUKS_TAG_KEY_ALIAS, value: StringToUint8Array(aliasAgreedKey) 523 }], inData: new Uint8Array([]) 524 } 525 return await huks.finishSession(handle.handle, dhAgreeAliceFinnish) 526} 527 528async function HuksDhAgreeInHuksTest( 529 aliasA: string, aliasB: string, 530 pubKeyA: huks.HuksReturnResult, pubKeyB: huks.HuksReturnResult, 531 aliasAgreedKeyFromA: string, aliasAgreedKeyFromB: string) { 532 533 const finishAliceResult = await HuksDhAgreeInHuks(aliasA, pubKeyB, aliasAgreedKeyFromA) 534 console.info(`ok! finishAliceResult in huks is 0x${Uint8ArrayToBigInt(finishAliceResult.outData).toString(16)}`) 535 const aliceAgreedExist = await huks.isKeyItemExist(aliasAgreedKeyFromA, emptyOptions) 536 console.info(`ok! aliceAgreedExist in huks is ${aliceAgreedExist}`) 537 538 const finishBobResult = await HuksDhAgreeInHuks(aliasB, pubKeyA, aliasAgreedKeyFromB) 539 console.info(`ok! finishBobResult in huks is 0x${Uint8ArrayToBigInt(finishBobResult.outData).toString(16)}`) 540 const bobAgreedExist = await huks.isKeyItemExist(aliasAgreedKeyFromB, emptyOptions) 541 console.info(`ok! bobAgreedExist in huks is ${bobAgreedExist}`) 542 543 await huks.deleteKeyItem(aliasAgreedKeyFromA, emptyOptions) 544 await huks.deleteKeyItem(aliasAgreedKeyFromB, emptyOptions) 545} 546 547export default async function HuksDhAgreeTest() { 548 const aliasAlice = 'alice' 549 const aliasBob = 'bob' 550 551 /* Call generateKeyItem to generate a key with alias of alice and a key with alias of bob. */ 552 await huks.generateKeyItem(aliasAlice, dhGenOptions) 553 await huks.generateKeyItem(aliasBob, dhGenOptions) 554 555 /* Export the public keys of asymmetric key pairs alice and bob. */ 556 const pubKeyAlice = await huks.exportKeyItem(aliasAlice, emptyOptions) 557 const pubKeyBob = await huks.exportKeyItem(aliasBob, emptyOptions) 558 559 /* Perform key agreement and return the shared secret generated to the caller for management. */ 560 await HuksDhAgreeExportTest(aliasAlice, aliasBob, pubKeyAlice, pubKeyBob) 561 562 /* Perform key agreement and let HUKS manage the shared secret generated. */ 563 await HuksDhAgreeInHuksTest(aliasAlice, aliasBob, pubKeyAlice, pubKeyBob, 'agreedKeyFromAlice', 'agreedKeyFromBob') 564 565 await huks.deleteKeyItem(aliasAlice, emptyOptions) 566 await huks.deleteKeyItem(aliasBob, emptyOptions) 567} 568``` 569