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