huks-guidelines.md 94.9 KB
Newer Older
A
Annie_wang 已提交
1

A
annie_wangli 已提交
2 3
# HUKS Development

A
Annie_wang 已提交
4 5 6 7 8 9 10 11
## Key Generation

The HUKS provides the capability of randomly generating keys for services. For a key generated by the HUKS, its plaintext will never be exposed outside throughout the lifecycle. This ensures that no one can access the plaintext of the key. Even the service that generates the key can call APIs provided by the HUKS to perform key operations and obtain the operation result, rather than accessing the key.

**<font size=5>How to Develop</font>**

Use [huks.generateKeyItem(keyAlias,options,callback)](../reference/apis/js-apis-huks.md#huksgeneratekeyitem9) to generate a key. You need to pass in the key alias in **keyAlias**, a key attribute set in **options**, and **callback** to result the result asynchronously. For details about the APIs, see [HUKS](../reference/apis/js-apis-huks.md).

A
Annie_wang 已提交
12 13


A
Annie_wang 已提交
14 15 16
1. Determine the key alias.
2. Initialize the key attributes.<br>Use [HuksParam](../reference/apis/js-apis-huks.md#huksparam) to encapsulate key attributes. Use a **HuksParam** array to assign values to the **properties** field of [HuksOptions](../reference/apis/js-apis-huks.md#huksoptions). The parameters [HuksKeyAlg](../reference/apis/js-apis-huks.md#hukskeyalg), [HuksKeySize](../reference/apis/js-apis-huks.md#hukskeysize), and [HuksKeyPurpose](../reference/apis/js-apis-huks.md#hukskeypurpose) are mandatory.
3. Pass in the key alias and key parameter set to generate a key.
A
Annie_wang 已提交
17

A
Annie_wang 已提交
18 19


A
Annie_wang 已提交
20
> **NOTE**
A
Annie_wang 已提交
21
>
A
Annie_wang 已提交
22
> The key alias cannot exceed 64 bytes.
A
Annie_wang 已提交
23

A
Annie_wang 已提交
24
**Sample code**
A
Annie_wang 已提交
25 26

```ts
A
Annie_wang 已提交
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
/*
 * Generate a DH key and return the result by a callback.
 */
import huks from '@ohos.security.huks';

/*
 * Determine the key alias and encapsulate the key attribute set.
 */
let keyAlias = 'dh_key';
let properties = new Array();
properties[0] = {
    tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
    value: huks.HuksKeyAlg.HUKS_ALG_DH
}
properties[1] = {
    tag: huks.HuksTag.HUKS_TAG_PURPOSE,
    value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_AGREE
}
properties[2] = {
    tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
    value: huks.HuksKeySize.HUKS_DH_KEY_SIZE_2048
}
properties[3] = {
    tag: huks.HuksTag.HUKS_TAG_DIGEST,
    value: huks.HuksKeyDigest.HUKS_DIGEST_SHA256
}
let huksOptions = {
    properties: properties,
    inData: new Uint8Array(new Array())
}

/*
 * Generate a key.
 */
function generateKeyItem(keyAlias: string, huksOptions: huks.HuksOptions) {
    return new Promise((resolve, reject) => {
        try {
            huks.generateKeyItem(keyAlias, huksOptions, function (error, data) {
                if (error) {
                    reject(error);
                } else {
                    resolve(data);
                }
            });
        } catch (error) {
            throw (error);
        }
    });
}

async function publicGenKeyFunc(keyAlias: string, huksOptions: huks.HuksOptions) {
    console.info(`enter callback generateKeyItem`);
    try {
        await generateKeyItem(keyAlias, huksOptions)
            .then((data) => {
                console.info(`callback: generateKeyItem success, data = ${JSON.stringify(data)}`);
            })
            .catch(error => {
                console.error(`callback: generateKeyItem failed, code: ${error.code}, msg: ${error.message}`);
            });
    } catch (error) {
        console.error(`callback: generateKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
    }
}


async function TestGenKey() {
    await publicGenKeyFunc(keyAlias, huksOptions);
}
A
Annie_wang 已提交
96 97
```

A
Annie_wang 已提交
98 99 100 101
## Key Import
If the key is generated outside the HUKS (for example, generated through key agreement or by a server), the application can import the key to the HUKS for management. The HUKS supports import of keys in plaintext. However, if keys are imported in plaintext, the keys are exposed in the REE memory. This operation applies to lightweight devices or security-insensitive services. For security-sensitive services, use the secure import provided by the HUKS. Secure import allows the keys generate keys by services to be transferred to the HUKS through an end-to-end encrypted transmission channel.

Once a key is imported to the HUKS, its plaintext will not be exposed outside the HUKS throughout the lifecycle of the key.
A
Annie_wang 已提交
102 103 104



A
Annie_wang 已提交
105
### Importing a Key in Plaintext
A
Annie_wang 已提交
106 107


A
Annie_wang 已提交
108
Use [huks.importKeyItem(keyAlias,options,callback)](../reference/apis/js-apis-huks.md#huksimportkeyitem9) to import a key in plaintext. You need to pass in the key alias in **keyAlias**, key material and attribute set in **options**, and **callback** to return the result asynchronously. For details about the APIs, see [HUKS](../reference/apis/js-apis-huks.md).
A
Annie_wang 已提交
109 110


A
Annie_wang 已提交
111 112 113 114
1. Determine the key alias.
2. Encapsulate the key material and key attribute set.<br>The key material must comply with [HUKS key material formats](./huks-appendix.md#key-material-formats). The **inData** value of [HuksOptions](../reference/apis/js-apis-huks.md#huksoptions) must be in the Uint8Array form. Encapsulate key attributes in [HuksParam](../reference/apis/js-apis-huks.md#huksparam), and use a **HuksParam** array to assign values to the **properties** field. The key attribute set must contain [HuksKeyAlg](../reference/apis/js-apis-huks.md#hukskeyalg), [HuksKeySize](../reference/apis/js-apis-huks.md#hukskeysize), and [HuksKeyPurpose](../reference/apis/js-apis-huks.md#hukskeypurpose).
3. Import the key.

A
Annie_wang 已提交
115

A
Annie_wang 已提交
116 117

**Sample code**
A
Annie_wang 已提交
118 119

```ts
A
Annie_wang 已提交
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
/*
 /* Import an AES key of 256 bits. */
 */
 
/* Key */
let plainTextSize32 = new Uint8Array([
  0xfb, 0x8b, 0x9f, 0x12, 0xa0, 0x83, 0x19, 0xbe, 0x6a, 0x6f, 0x63, 0x2a, 0x7c, 0x86, 0xba, 0xca,
  0x64, 0x0b, 0x88, 0x96, 0xe2, 0xfa, 0x77, 0xbc, 0x71, 0xe3, 0x0f, 0x0f, 0x9e, 0x3c, 0xe5, 0xf9
]);

/*
 * Determine the key alias.
 */
let keyAlias = 'AES256Alias_sample';

/*
 * Encapsulate the key attribute set and key material.
 */ 
A
Annie_wang 已提交
138 139 140
let properties = new Array();
properties[0] = {
    tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
A
Annie_wang 已提交
141
    value: huks.HuksKeyAlg.HUKS_ALG_AES
A
Annie_wang 已提交
142 143 144
};
properties[1] = {
    tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
A
Annie_wang 已提交
145
    value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_256
A
Annie_wang 已提交
146 147 148 149
};
properties[2] = {
    tag: huks.HuksTag.HUKS_TAG_PURPOSE,
    value:
A
Annie_wang 已提交
150
    huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT | huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT
A
Annie_wang 已提交
151 152
};
let options = {
A
Annie_wang 已提交
153 154
    properties: properties,
    inData: plainTextSize32
A
Annie_wang 已提交
155
};
A
Annie_wang 已提交
156 157 158 159

/*
 * Import the key.
 */
A
Annie_wang 已提交
160
try {
A
Annie_wang 已提交
161
    huks.importKeyItem(keyAlias, options, function (error, data) {
A
Annie_wang 已提交
162
        if (error) {
A
Annie_wang 已提交
163
            console.error(`callback: importKeyItem failed, code: ${error.code}, msg: ${error.message}`);
A
Annie_wang 已提交
164
        } else {
A
Annie_wang 已提交
165
            console.info(`callback: importKeyItem success`);
A
Annie_wang 已提交
166 167 168
        }
    });
} catch (error) {
A
Annie_wang 已提交
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206
    console.error(`callback: importKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
}
```

**Verification**

Check whether the key exists. If yes, the key is imported successfully.

**Sample code**

```ts
import huks from '@ohos.security.huks';

let keyAlias = 'AES256Alias_sample';
let isKeyExist;

let keyProperties = new Array();
keyProperties[0] = {
    tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
    value: huks.HuksKeyAlg.HUKS_ALG_AES,
}
let huksOptions = {
    properties: keyProperties, // It cannot be empty.
    inData: new Uint8Array(new Array()) // It cannot be empty.
}
try {
    huks.isKeyItemExist(keyAlias, huksOptions, function (error, data) {
        if (error) {
            console.error(`callback: isKeyItemExist failed, code: ${error.code}, msg: ${error.message}`);
        } else {
            if (data !== null && data.valueOf() !== null) {
                isKeyExist = data.valueOf();
                console.info(`callback: isKeyItemExist success, isKeyExist = ${isKeyExist}`);
            }
        }
    });
} catch (error) {
    console.error(`callback: isKeyItemExist input arg invalid, code: ${error.code}, msg: ${error.message}`);
A
Annie_wang 已提交
207 208 209
}
```

A
Annie_wang 已提交
210
### Importing a Wrapped Key
A
Annie_wang 已提交
211

A
Annie_wang 已提交
212
Compared with import of plaintext, secure import has complex key material and operations. The following figure illustrates the development process of secure import.
A
Annie_wang 已提交
213 214 215



A
Annie_wang 已提交
216
**Figure 2** Development process of secure import
A
Annie_wang 已提交
217

A
Annie_wang 已提交
218
![huks_import_wrapped_key](figures/huks_import_wrapped_key.png)
A
Annie_wang 已提交
219 220 221 222




A
Annie_wang 已提交
223
**Available APIs**
A
Annie_wang 已提交
224

A
Annie_wang 已提交
225
You need to use the APIs for generating a key, exporting a public key, importing a wrapped key, and deleting a key in sequence.
A
Annie_wang 已提交
226

A
Annie_wang 已提交
227 228 229 230 231
**Table 1** APIs for secure import

| API                     | Description                |
| -------------------------------------- | ----------------------------|
|generateKeyItem(keyAlias: string, options: HuksOptions, callback: AsyncCallback\<void>) : void| Generates a key.|
232 233 234
|exportKeyItem(keyAlias: string, options: HuksOptions, callback: AsyncCallback\<HuksReturnResult>) : void| Exports the public key of a key pair.|
|importWrappedKeyItem(keyAlias: string, wrappingKeyAlias: string, options: HuksOptions, callback: AsyncCallback\<void>) : void|Imports a wrapped key.|
|deleteKeyItem(keyAlias: string, options: HuksOptions, callback: AsyncCallback\<void>) : void|Deletes a key.|
A
Annie_wang 已提交
235 236

>**NOTE**<br>The public key plaintext material returned by **exportKeyItem()** is encapsulated in X.509 format, and the key material to be imported by **importWrappedKeyItem()** must be encapsulated in **Length<sub>Data</sub>-Data** format. Specifically, the application needs to apply for a Uint8Array and encapsulate the Uint8Array in the sequence listed in the following table.
A
Annie_wang 已提交
237

A
Annie_wang 已提交
238
**Table 2** Format of the wrapped key material
A
Annie_wang 已提交
239

A
Annie_wang 已提交
240 241 242 243 244 245 246 247 248
| Content| Public Key Length (L<sub>pk2</sub>)| Public Key pk2| k2 AAD2 Length L<sub>AAD2</sub>| k2 Encryption Parameter AAD2|  k2 Nonce2 Length L<sub>Nonce2</sub>| k2 Encryption Parameter Nonce2|
| :--: |:----:|:----: |:----: | :----:  | :----:|:----:|
|Length| 4 bytes|L<sub>pk2</sub> bytes| 4 bytes| L<sub>AAD2</sub> bytes| 4 bytes| L<sub>Nonce2</sub> bytes|
| Content| k2 AEAD2 Length L<sub>AEAD2</sub>| k2 Encryption Parameter AEAD2| k3 Ciphertext Length L<sub>k3_enc</sub>| k3 Ciphertext k3_enc|  k3 AAD3 Length L<sub>AAD3</sub>| k3 Encryption Parameter AAD3|
|Length| 4 bytes|L<sub>AEAD2</sub> bytes| 4 bytes| L<sub>k3_enc</sub> bytes| 4 bytes| L<sub>AAD3</sub> bytes|
| Content| k3 Nonce3 Length L<sub>Nonce3</sub>| k3 Encryption Parameter Nonce3| k3 AEAD3 Length L<sub>AEAD3</sub>| k3 Encryption Parameter AEAD3|  Length of **k1'_size** L<sub>k1'_size</sub>| Key Plaintext Material Length k1'_size|
|Length| 4 bytes|L<sub>Nonce3</sub> bytes| 4 bytes| L<sub>AEAD3</sub> bytes| 4 bytes| L<sub>k1'_size</sub> bytes|
|Content|k1' Ciphertext Length L<sub>k1'_enc</sub>| k1' ciphertext k1'_enc| | | | |
|Length| 4 bytes|L<sub>k1'_enc</sub> bytes| | | | |
A
Annie_wang 已提交
249

A
Annie_wang 已提交
250
**How to Develop**
A
Annie_wang 已提交
251

A
Annie_wang 已提交
252 253 254 255 256 257 258 259 260
The following example provides the development involving HUKS APIs (using the ECDH key agreement suite). The operations performed by the service are not included.
1. Convert the key material to the HUKS format.
2. Generate a wrapping key (a key used for secure import).
3. Export the public key material.
4. Wrap the key material to be imported.
5. Import the wrapped key material.
6. Delete the wrapping key.

**Sample code**
A
Annie_wang 已提交
261 262

```ts
A
Annie_wang 已提交
263 264 265
/*
 * Import an SM2 key and return the result by a callback.
 */
A
Annie_wang 已提交
266 267
import huks from '@ohos.security.huks';

A
Annie_wang 已提交
268 269 270 271 272 273
/*
 * Determine the key alias.
 */
let importAlias = "importAlias";
let wrapAlias = "wrappingKeyAlias";
let exportKey;
A
Annie_wang 已提交
274

A
Annie_wang 已提交
275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293
/*
 * Convert the key material into a HUKS ECC-P-256 key pair for secure import. 
 */
let inputEccPair = new Uint8Array([
    0x02, 0x00, 0x00, 0x00, // key algorithm: huks.HuksKeyAlg.HUKS_ALG_ECC = 2
    0x00, 0x01, 0x00, 0x00, // key size: 256 bits
    0x20, 0x00, 0x00, 0x00, // Coordinate x length: 32 bytes
    0x20, 0x00, 0x00, 0x00, // Coordinate y length: 32 bytes
    0x20, 0x00, 0x00, 0x00, // Coordinate z length: 32 bytes
    // Coordinate x
    0xa5, 0xb8, 0xa3, 0x78, 0x1d, 0x6d, 0x76, 0xe0, 0xb3, 0xf5, 0x6f, 0x43, 0x9d, 0xcf, 0x60, 0xf6,
    0x0b, 0x3f, 0x64, 0x45, 0xa8, 0x3f, 0x1a, 0x96, 0xf1, 0xa1, 0xa4, 0x5d, 0x3e, 0x2c, 0x3f, 0x13,
    // Coordinate y
    0xd7, 0x81, 0xf7, 0x2a, 0xb5, 0x8d, 0x19, 0x3d, 0x9b, 0x96, 0xc7, 0x6a, 0x10, 0xf0, 0xaa, 0xbc,
    0x91, 0x6f, 0x4d, 0xa7, 0x09, 0xb3, 0x57, 0x88, 0x19, 0x6f, 0x00, 0x4b, 0xad, 0xee, 0x34, 0x35,
    // Coordinate z
    0xfb, 0x8b, 0x9f, 0x12, 0xa0, 0x83, 0x19, 0xbe, 0x6a, 0x6f, 0x63, 0x2a, 0x7c, 0x86, 0xba, 0xca,
    0x64, 0x0b, 0x88, 0x96, 0xe2, 0xfa, 0x77, 0xbc, 0x71, 0xe3, 0x0f, 0x0f, 0x9e, 0x3c, 0xe5, 0xf9
    ]);
A
Annie_wang 已提交
294

A
Annie_wang 已提交
295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323
/*
 * Encapsulate the key attribute set.
 */
// Attribute set for the wrapping key.
let properties = new Array();
properties[0] = {
    tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
    value: huks.HuksKeyAlg.HUKS_ALG_ECC
};
properties[1] = {
    tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
    value: huks.HuksKeySize.HUKS_ECC_KEY_SIZE_256
};
properties[2] = {
    tag: huks.HuksTag.HUKS_TAG_PURPOSE,
    value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_UNWRAP
};
properties[3] = {
    tag: huks.HuksTag.HUKS_TAG_DIGEST,
    value: huks.HuksKeyDigest.HUKS_DIGEST_SHA256
};
properties[4] = {
    tag: huks.HuksTag.HUKS_TAG_IMPORT_KEY_TYPE,
    value: huks.HuksImportKeyType.HUKS_KEY_TYPE_KEY_PAIR,
};
let huksOptions = {
    properties: properties,
    inData: inputEccPair
};
A
Annie_wang 已提交
324

A
Annie_wang 已提交
325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354
// Attribute set of the AES256 key to be imported. 
let importProperties = new Array();
importProperties[0] = {
    tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
    value: huks.HuksKeyAlg.HUKS_ALG_AES
};
importProperties[1] = {
    tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
    value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_256
};
importProperties[2] = {
    tag: huks.HuksTag.HUKS_TAG_PURPOSE,
    value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT | huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT
};
importProperties[3] = {
    tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE,
    value: huks.HuksCipherMode.HUKS_MODE_CBC
};
importProperties[4] = {
    tag: huks.HuksTag.HUKS_TAG_PADDING,
    value: huks.HuksKeyPadding.HUKS_PADDING_NONE
};
importProperties[5] = {
    tag: huks.HuksTag.HUKS_TAG_UNWRAP_ALGORITHM_SUITE,
    value: huks.HuksUnwrapSuite.HUKS_UNWRAP_SUITE_ECDH_AES_256_GCM_NOPADDING // Use the ECDH+AES256GCM suite.
};
let importOptions = {
    properties: importProperties,
    inData: new Uint8Array(new Array())
};
A
Annie_wang 已提交
355

A
Annie_wang 已提交
356 357
// Export the public key of the key pair.
function exportKeyItem(keyAlias:string, huksOptions:huks.HuksOptions, throwObject) : Promise<huks.HuksReturnResult> {
A
Annie_wang 已提交
358 359
    return new Promise((resolve, reject) => {
        try {
A
Annie_wang 已提交
360
            huks.exportKeyItem(keyAlias, huksOptions, function (error, data) {
A
Annie_wang 已提交
361 362 363 364 365 366 367
                if (error) {
                    reject(error);
                } else {
                    resolve(data);
                }
            });
        } catch (error) {
A
Annie_wang 已提交
368 369
            throwObject.isThrow = true;
            throw(error);
A
Annie_wang 已提交
370 371 372 373
        }
    });
}

A
Annie_wang 已提交
374
async function publicExportKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
A
Annie_wang 已提交
375
    console.info(`enter callback export`);
A
Annie_wang 已提交
376
    let throwObject = {isThrow: false};
A
Annie_wang 已提交
377
    try {
A
Annie_wang 已提交
378 379
        await exportKeyItem(keyAlias, huksOptions, throwObject)
            .then ((data) => {
A
Annie_wang 已提交
380
                console.info(`callback: exportKeyItem success, data = ${JSON.stringify(data)}`);
A
Annie_wang 已提交
381
                exportKey = data.outData;
A
Annie_wang 已提交
382 383
            })
            .catch(error => {
A
Annie_wang 已提交
384 385 386 387 388
                if (throwObject.isThrow) {
                    throw(error);
                } else {
                    console.error(`callback: exportKeyItem failed, code: ${error.code}, msg: ${error.message}`);
                }
A
Annie_wang 已提交
389 390 391 392 393 394
            });
    } catch (error) {
        console.error(`callback: exportKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
    }
}

A
Annie_wang 已提交
395 396
// Generate a wrapping key (the key is imported here).
function importKeyItem(keyAlias:string, huksOptions:huks.HuksOptions, throwObject) {
A
Annie_wang 已提交
397 398
    return new Promise((resolve, reject) => {
        try {
A
Annie_wang 已提交
399
            huks.importKeyItem(keyAlias, huksOptions, function (error, data) {
A
Annie_wang 已提交
400 401
                if (error) {
                    reject(error);
A
Annie_wang 已提交
402
                } else {
A
Annie_wang 已提交
403 404 405 406
                    resolve(data);
                }
            });
        } catch (error) {
A
Annie_wang 已提交
407 408
            throwObject.isThrow = true;
            throw(error);
A
Annie_wang 已提交
409 410 411 412
        }
    });
}

A
Annie_wang 已提交
413
async function publicImportKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
A
Annie_wang 已提交
414
    console.info(`enter promise importKeyItem`);
A
Annie_wang 已提交
415
    let throwObject = {isThrow: false};
A
Annie_wang 已提交
416
    try {
A
Annie_wang 已提交
417 418
        await importKeyItem(keyAlias, huksOptions, throwObject)
            .then ((data) => {
A
Annie_wang 已提交
419 420 421
                console.info(`callback: importKeyItem success, data = ${JSON.stringify(data)}`);
            })
            .catch(error => {
A
Annie_wang 已提交
422 423 424 425 426
                if (throwObject.isThrow) {
                    throw(error);
                } else {
                    console.error(`callback: importKeyItem failed, code: ${error.code}, msg: ${error.message}`);
                }
A
Annie_wang 已提交
427 428 429 430 431 432
            });
    } catch (error) {
        console.error(`callback: importKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
    }
}

A
Annie_wang 已提交
433 434 435 436
// Perform secure import.
async function publicImportWrappedKey(keyAlias:string, wrappingKeyAlias:string, huksOptions:huks.HuksOptions) {
    console.info(`enter callback importWrappedKeyItem`);
    var throwObject = {isThrow: false};
A
Annie_wang 已提交
437
    try {
A
Annie_wang 已提交
438 439 440
        await importWrappedKeyItem(keyAlias, wrappingKeyAlias, huksOptions, throwObject)
            .then ((data) => {
                console.info(`callback: importWrappedKeyItem success, data = ${JSON.stringify(data)}`);
A
Annie_wang 已提交
441 442
            })
            .catch(error => {
A
Annie_wang 已提交
443 444 445 446 447
                if (throwObject.isThrow) {
                    throw(error);
                } else {
                    console.error(`callback: importWrappedKeyItem failed, code: ${error.code}, msg: ${error.message}`);
                }
A
Annie_wang 已提交
448 449
            });
    } catch (error) {
A
Annie_wang 已提交
450
        console.error(`callback: importWrappedKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
A
Annie_wang 已提交
451 452 453
    }
}

A
Annie_wang 已提交
454
function importWrappedKeyItem(keyAlias:string, wrappingKeyAlias:string, huksOptions:huks.HuksOptions, throwObject) {
A
Annie_wang 已提交
455 456
    return new Promise((resolve, reject) => {
        try {
A
Annie_wang 已提交
457
            huks.importWrappedKeyItem(keyAlias, wrappingKeyAlias, huksOptions, function (error, data) {
A
Annie_wang 已提交
458 459 460 461 462 463 464
                if (error) {
                    reject(error);
                } else {
                    resolve(data);
                }
            });
        } catch (error) {
A
Annie_wang 已提交
465 466
            throwObject.isThrow = true;
            throw(error);
A
Annie_wang 已提交
467 468 469
        }
    });
}
A
Annie_wang 已提交
470

A
Annie_wang 已提交
471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505
// Delete the wrapping key.
function deleteKeyItem(keyAlias:string, huksOptions:huks.HuksOptions, throwObject) {
    return new Promise((resolve, reject) => {
        try {
            huks.deleteKeyItem(keyAlias, huksOptions, function (error, data) {
                if (error) {
                    reject(error);
                } else {
                    resolve(data);
                }
            });
        } catch (error) {
            throwObject.isThrow = true;
            throw(error);
        }
    });
}

async function publicDeleteKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
    console.info(`enter callback deleteKeyItem`);
    let throwObject = {isThrow: false};
    try {
        await deleteKeyItem(keyAlias, huksOptions, throwObject)
            .then ((data) => {
                console.info(`callback: deleteKeyItem key success, data = ${JSON.stringify(data)}`);
            })
            .catch(error => {
                if (throwObject.isThrow) {
                    throw(error);
                } else {
                    console.error(`callback: deleteKeyItem failed, code: ${error.code}, msg: ${error.message}`);
                }
            });
    } catch (error) {
        console.error(`callback: deletKeeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
A
Annie_wang 已提交
506
    }
A
Annie_wang 已提交
507
}
A
Annie_wang 已提交
508

A
Annie_wang 已提交
509 510 511 512 513 514
async function ImportWrappedKeyNormalTest() {
    console.info(`enter ImportWrapKey test`);
    /*
     * Generate a wrapping key (the key is imported here).
     */
    await publicImportKeyFunc(wrapAlias, huksOptions);
A
Annie_wang 已提交
515

A
Annie_wang 已提交
516 517 518 519
    /*
     * Export the public key material of the wrapping key.
     */
    await publicExportKeyFunc(wrapAlias, huksOptions);
A
Annie_wang 已提交
520

A
Annie_wang 已提交
521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581
    /*----------------------------------------------------------------------------------------------
     * The processes of generating an ECC key pair, performing ECDH key agreement, generating a k3, and encrypting k1' and k3 on the service side are omitted.
     *----------------------------------------------------------------------------------------------*/

    /* Encapsulate the key material to be imported.
     * Create the importOptions.inData field in the following format:
     * pk2 length (4 bytes) + pk2 data + AAD2 length (4 bytes) + AAD2 data +
     * Nonce2 length (4 bytes) + Nonce2 data + AEAD2 length (4 bytes) + AEAD2 data +
     * k3 ciphertext length (4 bytes) + k3 data + AAD3 length (4 bytes) + AAD3 data +
     * Nonce3 length (4 bytes) +Nonce3 data + AEAD3 length (4 bytes) + AEAD3 data +
     * k1'_size length (4 bytes) + k1'_size + k1'_enc length (4 bytes) + k1'_enc data
     */
    let inputKey = new Uint8Array([
        0x5b, 0x00, 0x00, 0x00, // ECC-P-256 public key length (DER format defined in X.509): 91
        // ECC-P-256 public key
        0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a,
        0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0xc0, 0xfe, 0x1c, 0x67, 0xde,
        0x86, 0x0e, 0xfb, 0xaf, 0xb5, 0x85, 0x52, 0xb4, 0x0e, 0x1f, 0x6c, 0x6c, 0xaa, 0xc5, 0xd9, 0xd2,
        0x4d, 0xb0, 0x8a, 0x72, 0x24, 0xa1, 0x99, 0xaf, 0xfc, 0x3e, 0x55, 0x5a, 0xac, 0x99, 0x3d, 0xe8,
        0x34, 0x72, 0xb9, 0x47, 0x9c, 0xa6, 0xd8, 0xfb, 0x00, 0xa0, 0x1f, 0x9f, 0x7a, 0x41, 0xe5, 0x44,
        0x3e, 0xb2, 0x76, 0x08, 0xa2, 0xbd, 0xe9, 0x41, 0xd5, 0x2b, 0x9e,

        0x10, 0x00, 0x00, 0x00, // AAD2 length: 16
        // AAD2
        0xbf, 0xf9, 0x69, 0x41, 0xf5, 0x49, 0x85, 0x31, 0x35, 0x14, 0x69, 0x12, 0x57, 0x9c, 0xc8, 0xb7,

        0x10, 0x00, 0x00, 0x00, // Nonce2 length: 16
        // Nonce2
        0x2d, 0xb7, 0xf1, 0x5a, 0x0f, 0xb8, 0x20, 0xc5, 0x90, 0xe5, 0xca, 0x45, 0x84, 0x5c, 0x08, 0x08,

        0x10, 0x00, 0x00, 0x00, // AEAD2 length: 16
        // AEAD2
        0x43, 0x25, 0x1b, 0x2f, 0x5b, 0x86, 0xd8, 0x87, 0x04, 0x4d, 0x38, 0xc2, 0x65, 0xcc, 0x9e, 0xb7,

        0x20, 0x00, 0x00, 0x00, // k3 ciphertext length: 32
        // k3 ciphertext
        0xf4, 0xe8, 0x93, 0x28, 0x0c, 0xfa, 0x4e, 0x11, 0x6b, 0xe8, 0xbd, 0xa8, 0xe9, 0x3f, 0xa7, 0x8f,
        0x2f, 0xe3, 0xb3, 0xbf, 0xaf, 0xce, 0xe5, 0x06, 0x2d, 0xe6, 0x45, 0x5d, 0x19, 0x26, 0x09, 0xe7,

        0x10, 0x00, 0x00, 0x00, // AAD3 length: 16
        // AAD3
        0xf4, 0x1e, 0x7b, 0x01, 0x7a, 0x84, 0x36, 0xa4, 0xa8, 0x1c, 0x0d, 0x3d, 0xde, 0x57, 0x66, 0x73,

        0x10, 0x00, 0x00, 0x00, // Nonce3 length: 16
        // Nonce3
        0xe3, 0xff, 0x29, 0x97, 0xad, 0xb3, 0x4a, 0x2c, 0x50, 0x08, 0xb5, 0x68, 0xe1, 0x90, 0x5a, 0xdc,

        0x10, 0x00, 0x00, 0x00, // AEAD3 length: 16
        // AEAD3
        0x26, 0xae, 0xdc, 0x4e, 0xa5, 0x6e, 0xb1, 0x38, 0x14, 0x24, 0x47, 0x1c, 0x41, 0x89, 0x63, 0x11,

        0x04, 0x00, 0x00, 0x00, // Length of k1_size: 4 bytes
        // k1_size: 32 bytes
        0x20, 0x00, 0x00, 0x00,

        0x20, 0x00, 0x00, 0x00, // Ciphertext length of the key to be imported: 32 bytes
        // Ciphertext of the key to be imported
        0x0b, 0xcb, 0xa9, 0xa8, 0x5f, 0x5a, 0x9d, 0xbf, 0xa1, 0xfc, 0x72, 0x74, 0x87, 0x79, 0xf2, 0xf4,
        0x22, 0x0c, 0x8a, 0x4d, 0xd8, 0x7e, 0x10, 0xc8, 0x44, 0x17, 0x95, 0xab, 0x3b, 0xd2, 0x8f, 0x0a
    ]);
    importOptions.inData = inputKey;
A
Annie_wang 已提交
582

A
Annie_wang 已提交
583 584 585 586
    /*
     * Import the wrapped key material.
     */
    await publicImportWrappedKey(importAlias, wrapAlias, importOptions);
A
Annie_wang 已提交
587

A
Annie_wang 已提交
588 589 590 591
    /*
     * Delete the wrapping key.
     */
     await publicDeleteKeyFunc(wrapAlias, huksOptions);
A
Annie_wang 已提交
592
}
A
Annie_wang 已提交
593
```
A
Annie_wang 已提交
594

A
Annie_wang 已提交
595
**Verification**
A
Annie_wang 已提交
596

A
Annie_wang 已提交
597
Check whether the key exists. If yes, the key is imported successfully.
A
Annie_wang 已提交
598

A
Annie_wang 已提交
599
**Sample code**
A
Annie_wang 已提交
600

A
Annie_wang 已提交
601 602
```ts
import huks from '@ohos.security.huks';
A
Annie_wang 已提交
603

A
Annie_wang 已提交
604 605 606 607 608
/*
 * Determine the key alias and encapsulate the key attribute set.
 */
let keyAlias = 'importAlias';
let isKeyExist;
A
Annie_wang 已提交
609

A
Annie_wang 已提交
610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627
let keyProperties = new Array();
keyProperties[0] = {
    tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
    value: huks.HuksKeyAlg.HUKS_ALG_AES,
}
let huksOptions = {
    properties: keyProperties, // It cannot be empty.
    inData: new Uint8Array(new Array()) // It cannot be empty.
}
try {
    huks.isKeyItemExist(keyAlias, huksOptions, function (error, data) {
        if (error) {
            console.error(`callback: isKeyItemExist failed, code: ${error.code}, msg: ${error.message}`);
        } else {
            if (data !== null && data.valueOf() !== null) {
                isKeyExist = data.valueOf();
                console.info(`callback: isKeyItemExist success, isKeyExist = ${isKeyExist}`);
            }
A
Annie_wang 已提交
628
        }
A
Annie_wang 已提交
629 630 631
    });
} catch (error) {
    console.error(`callback: isKeyItemExist input arg invalid, code: ${error.code}, msg: ${error.message}`);
A
Annie_wang 已提交
632 633 634 635
}
```


A
Annie_wang 已提交
636
## Common Key Operations
A
Annie_wang 已提交
637

A
Annie_wang 已提交
638
**When to Use**
A
Annie_wang 已提交
639

A
Annie_wang 已提交
640
To ensure data confidentiality and integrity, you may need to encrypt or decrypt data, generate or verify a signature, perform key agreement, and derive a key. The following describes common key operations. The following examples do not involve secondary identity access control. If secondary identity access control is involved, see [Key Access Control](#key-access-control).
A
Annie_wang 已提交
641

A
Annie_wang 已提交
642
**General Development Process**
A
Annie_wang 已提交
643

A
Annie_wang 已提交
644 645 646 647
The HUKS operates data based on key sessions. The general process is as follows:
1. (Mandatory) Use [huks.initSession()](../reference/apis/js-apis-huks.md#huksinitsession9) to initialize a key session.<br>You need to pass in the key alias and key operation parameters to initialize a key session, and obtain the session handle. The key operation parameters must contain the parameters required by the cipher algorithm, including the cipher algorithm, key size, key purpose, working mode, padding mode, hash mode, IV, nonce, and AAD. If access control is set for the key, other parameters are required. For details, see [Key Access Control](#key-access-control).
2. (Optional) Use [huks.updateSession()](../reference/apis/js-apis-huks.md#huksupdatesession9) to pass in data by segment.<br>Perform this step only if the data exceeds 100 KB or the cipher algorithm requires operations by data segment. Otherwise, skip this step.
3. (Mandatory) Use [huks.finishSession()](../reference/apis/js-apis-huks.md#huksfinishsession9) to finalize the key session operation.<br>Pass in the last data segment and perform the key session operation. If an error occurs during the process or the data passed in is not required, use [huks.abortSession()](../reference/apis/js-apis-huks.md#huksabortsession9) to abort the session.
A
Annie_wang 已提交
648

A
Annie_wang 已提交
649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692
### Encryption and Decryption
```ts
/*
 * Encrypt and decrypt data using an SM4 128-bit key and return the result in a callback.
 */
import huks from '@ohos.security.huks';

/*
 * Determine the key alias and encapsulate the key attribute set.
 */
let srcKeyAlias = 'sm4_Key';
let IV = '0000000000000000';
let cipherInData = 'Hks_SM4_Cipher_Test_101010101010101010110_string';
let encryptUpdateResult = new Array();
let handle;
let updateResult = new Array();
let finishOutData;

/* Configure the key generation parameter set and key encryption parameter set. */
let properties = new Array();
properties[0] = {
    tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
    value: huks.HuksKeyAlg.HUKS_ALG_SM4,
}
properties[1] = {
    tag: huks.HuksTag.HUKS_TAG_PURPOSE,
    value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT | huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT,
}
properties[2] = {
    tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
    value: huks.HuksKeySize.HUKS_SM4_KEY_SIZE_128,
}
properties[3] = {
    tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE,
    value: huks.HuksCipherMode.HUKS_MODE_CBC,
}
properties[4] = {
    tag: huks.HuksTag.HUKS_TAG_PADDING,
    value: huks.HuksKeyPadding.HUKS_PADDING_NONE,
}
let huksOptions = {
    properties: properties,
    inData: new Uint8Array(new Array())
}
A
Annie_wang 已提交
693

A
Annie_wang 已提交
694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722
let propertiesEncrypt = new Array();
propertiesEncrypt[0] = {
    tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
    value: huks.HuksKeyAlg.HUKS_ALG_SM4,
}
propertiesEncrypt[1] = {
    tag: huks.HuksTag.HUKS_TAG_PURPOSE,
    value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT,
}
propertiesEncrypt[2] = {
    tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
    value: huks.HuksKeySize.HUKS_SM4_KEY_SIZE_128,
}
propertiesEncrypt[3] = {
    tag: huks.HuksTag.HUKS_TAG_PADDING,
    value: huks.HuksKeyPadding.HUKS_PADDING_NONE,
}
propertiesEncrypt[4] = {
    tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE,
    value: huks.HuksCipherMode.HUKS_MODE_CBC,
}
propertiesEncrypt[5] = {
    tag: huks.HuksTag.HUKS_TAG_IV,
    value: StringToUint8Array(IV),
}
let encryptOptions = {
    properties: propertiesEncrypt,
    inData: new Uint8Array(new Array())
}
A
Annie_wang 已提交
723

A
Annie_wang 已提交
724 725 726 727 728 729 730 731 732
/* Modify the key encryption parameter set to the decryption parameter set. */
propertiesEncrypt.splice(1, 1, {
    tag: huks.HuksTag.HUKS_TAG_PURPOSE,
    value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT,
});
let decryptOptions = {
    properties: propertiesEncrypt,
    inData: new Uint8Array(new Array())
}
A
Annie_wang 已提交
733

A
Annie_wang 已提交
734 735 736 737 738 739 740
function StringToUint8Array(str) {
    let arr = [];
    for (let i = 0, j = str.length; i < j; ++i) {
        arr.push(str.charCodeAt(i));
    }
    return new Uint8Array(arr);
}
A
Annie_wang 已提交
741

A
Annie_wang 已提交
742 743 744 745 746 747 748
function Uint8ArrayToString(fileData) {
    let dataString = '';
    for (let i = 0; i < fileData.length; i++) {
        dataString += String.fromCharCode(fileData[i]);
    }
    return dataString;
}
A
Annie_wang 已提交
749

A
Annie_wang 已提交
750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765
function generateKeyItem(keyAlias:string, huksOptions:huks.HuksOptions, throwObject) {
    return new Promise((resolve, reject) => {
        try {
            huks.generateKeyItem(keyAlias, huksOptions, function (error, data) {
                if (error) {
                    reject(error);
                } else {
                    resolve(data);
                }
            });
        } catch (error) {
            throwObject.isThrow = true;
            throw(error);
        }
    });
}
A
Annie_wang 已提交
766

A
Annie_wang 已提交
767 768 769
async function publicGenKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
    console.info(`enter callback generateKeyItem`);
    let throwObject = {isThrow: false};
A
Annie_wang 已提交
770
    try {
A
Annie_wang 已提交
771 772 773
        await generateKeyItem(keyAlias, huksOptions, throwObject)
            .then((data) => {
                console.info(`callback: generateKeyItem success, data = ${JSON.stringify(data)}`);
A
Annie_wang 已提交
774 775
            })
            .catch(error => {
A
Annie_wang 已提交
776 777 778 779 780
                if (throwObject.isThrow) {
                    throw(error);
                } else {
                    console.error(`callback: generateKeyItem failed, code: ${error.code}, msg: ${error.message}`);
                }
A
Annie_wang 已提交
781 782
            });
    } catch (error) {
A
Annie_wang 已提交
783
        console.error(`callback: generateKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
A
Annie_wang 已提交
784
    }
A
Annie_wang 已提交
785 786
}

A
Annie_wang 已提交
787
function initSession(keyAlias:string, huksOptions:huks.HuksOptions, throwObject) : Promise<huks.HuksSessionHandle> {
A
Annie_wang 已提交
788
    return new Promise((resolve, reject) => {
A
Annie_wang 已提交
789
        try {
A
Annie_wang 已提交
790
            huks.initSession(keyAlias, huksOptions, function (error, data) {
A
Annie_wang 已提交
791 792 793 794 795 796 797
                if (error) {
                    reject(error);
                } else {
                    resolve(data);
                }
            });
        } catch (error) {
A
Annie_wang 已提交
798
            throwObject.isThrow = true;
A
Annie_wang 已提交
799 800
            throw(error);
        }
A
Annie_wang 已提交
801 802 803
    });
}

A
Annie_wang 已提交
804 805 806
async function publicInitFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
    console.info(`enter callback doInit`);
    let throwObject = {isThrow: false};
A
Annie_wang 已提交
807
    try {
A
Annie_wang 已提交
808
        await initSession(keyAlias, huksOptions, throwObject)
A
Annie_wang 已提交
809
            .then ((data) => {
A
Annie_wang 已提交
810 811
                console.info(`callback: doInit success, data = ${JSON.stringify(data)}`);
                handle = data.handle;
A
Annie_wang 已提交
812
            })
A
Annie_wang 已提交
813 814 815 816 817 818
            .catch((error) => {
                if (throwObject.isThrow) {
                    throw(error);
                } else {
                    console.error(`callback: doInit failed, code: ${error.code}, msg: ${error.message}`);
                }
A
Annie_wang 已提交
819 820
            });
    } catch (error) {
A
Annie_wang 已提交
821
        console.error(`callback: doInit input arg invalid, code: ${error.code}, msg: ${error.message}`);
A
Annie_wang 已提交
822 823 824
    }
}

A
Annie_wang 已提交
825
function updateSession(handle:number, huksOptions:huks.HuksOptions, throwObject) : Promise<huks.HuksReturnResult> {
A
Annie_wang 已提交
826 827
    return new Promise((resolve, reject) => {
        try {
A
Annie_wang 已提交
828
            huks.updateSession(handle, huksOptions, function (error, data) {
A
Annie_wang 已提交
829 830 831 832 833 834 835
                if (error) {
                    reject(error);
                } else {
                    resolve(data);
                }
            });
        } catch (error) {
A
Annie_wang 已提交
836
            throwObject.isThrow = true;
A
Annie_wang 已提交
837 838
            throw(error);
        }
A
Annie_wang 已提交
839 840 841
    });
}

A
Annie_wang 已提交
842 843 844
async function publicUpdateFunc(handle:number, huksOptions:huks.HuksOptions) {
    console.info(`enter callback doUpdate`);
    let throwObject = {isThrow: false};
A
Annie_wang 已提交
845
    try {
A
Annie_wang 已提交
846
        await updateSession(handle, huksOptions, throwObject)
A
Annie_wang 已提交
847
            .then ((data) => {
A
Annie_wang 已提交
848
                console.info(`callback: doUpdate success, data = ${JSON.stringify(data)}`);
A
Annie_wang 已提交
849 850
            })
            .catch(error => {
A
Annie_wang 已提交
851 852 853 854 855
                if (throwObject.isThrow) {
                    throw(error);
                } else {
                    console.error(`callback: doUpdate failed, code: ${error.code}, msg: ${error.message}`);
                }
A
Annie_wang 已提交
856 857
            });
    } catch (error) {
A
Annie_wang 已提交
858
        console.error(`callback: doUpdate input arg invalid, code: ${error.code}, msg: ${error.message}`);
A
Annie_wang 已提交
859 860 861
    }
}

A
Annie_wang 已提交
862
function finishSession(handle:number, huksOptions:huks.HuksOptions, throwObject) : Promise<huks.HuksReturnResult> {
A
Annie_wang 已提交
863
    return new Promise((resolve, reject) => {
A
Annie_wang 已提交
864
        try {
A
Annie_wang 已提交
865
            huks.finishSession(handle, huksOptions, function (error, data) {
A
Annie_wang 已提交
866 867 868 869 870 871 872
                if (error) {
                    reject(error);
                } else {
                    resolve(data);
                }
            });
        } catch (error) {
A
Annie_wang 已提交
873
            throwObject.isThrow = true;
A
Annie_wang 已提交
874 875
            throw(error);
        }
A
Annie_wang 已提交
876 877 878
    });
}

A
Annie_wang 已提交
879 880 881
async function publicFinishFunc(handle:number, huksOptions:huks.HuksOptions) {
    console.info(`enter callback doFinish`);
    let throwObject = {isThrow: false};
A
Annie_wang 已提交
882
    try {
A
Annie_wang 已提交
883
        await finishSession(handle, huksOptions, throwObject)
A
Annie_wang 已提交
884
            .then ((data) => {
A
Annie_wang 已提交
885 886
                finishOutData = data.outData;
                console.info(`callback: doFinish success, data = ${JSON.stringify(data)}`);
A
Annie_wang 已提交
887 888
            })
            .catch(error => {
A
Annie_wang 已提交
889 890 891 892 893
                if (throwObject.isThrow) {
                    throw(error);
                } else {
                    console.error(`callback: doFinish failed, code: ${error.code}, msg: ${error.message}`);
                }
A
Annie_wang 已提交
894 895
            });
    } catch (error) {
A
Annie_wang 已提交
896
        console.error(`callback: doFinish input arg invalid, code: ${error.code}, msg: ${error.message}`);
A
Annie_wang 已提交
897 898 899
    }
}

A
Annie_wang 已提交
900
function deleteKeyItem(keyAlias:string, huksOptions:huks.HuksOptions, throwObject) {
A
Annie_wang 已提交
901 902 903 904 905 906 907 908 909 910
    return new Promise((resolve, reject) => {
        try {
            huks.deleteKeyItem(keyAlias, huksOptions, function (error, data) {
                if (error) {
                    reject(error);
                } else {
                    resolve(data);
                }
            });
        } catch (error) {
A
Annie_wang 已提交
911
            throwObject.isThrow = true;
A
Annie_wang 已提交
912 913 914 915 916
            throw(error);
        }
    });
}

A
Annie_wang 已提交
917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935
async function publicDeleteKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
    console.info(`enter callback deleteKeyItem`);
    let throwObject = {isThrow: false};
    try {
        await deleteKeyItem(keyAlias, huksOptions, throwObject)
            .then ((data) => {
                console.info(`callback: deleteKeyItem key success, data = ${JSON.stringify(data)}`);
            })
            .catch(error => {
                if (throwObject.isThrow) {
                    throw(error);
                } else {
                    console.error(`callback: deleteKeyItem failed, code: ${error.code}, msg: ${error.message}`);
                }
            });
    } catch (error) {
        console.error(`callback: deletKeeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
    }
}
A
Annie_wang 已提交
936

A
Annie_wang 已提交
937 938 939
async function testSm4Cipher() {
    /* Generate a key. */
    await publicGenKeyFunc(srcKeyAlias, huksOptions);
A
Annie_wang 已提交
940

A
Annie_wang 已提交
941 942
    /* Encrypt the key. */
    await publicInitFunc(srcKeyAlias, encryptOptions);
A
Annie_wang 已提交
943

A
Annie_wang 已提交
944 945 946
    encryptOptions.inData = StringToUint8Array(cipherInData);
    await publicUpdateFunc(handle, encryptOptions);
    encryptUpdateResult = updateResult;
A
Annie_wang 已提交
947

A
Annie_wang 已提交
948 949 950 951 952 953 954
    encryptOptions.inData = new Uint8Array(new Array());
    await publicFinishFunc(handle, encryptOptions);
    if (finishOutData === cipherInData) {
        console.info('test finish encrypt err ');
    } else {
        console.info('test finish encrypt success');
    }
A
Annie_wang 已提交
955

A
Annie_wang 已提交
956 957
    /* Decrypt the key. */
    await publicInitFunc(srcKeyAlias, decryptOptions);
A
Annie_wang 已提交
958

A
Annie_wang 已提交
959 960
    decryptOptions.inData = new Uint8Array(encryptUpdateResult);
    await publicUpdateFunc(handle, decryptOptions);
A
Annie_wang 已提交
961

A
Annie_wang 已提交
962 963 964 965 966 967
    decryptOptions.inData = new Uint8Array(new Array());
    await publicFinishFunc(handle, decryptOptions);
    if (finishOutData === cipherInData) {
        console.info('test finish decrypt success ');
    } else {
        console.info('test finish decrypt err');
A
Annie_wang 已提交
968
    }
A
Annie_wang 已提交
969 970

    await publicDeleteKeyFunc(srcKeyAlias, huksOptions);
A
Annie_wang 已提交
971 972 973
}
```

A
Annie_wang 已提交
974 975 976 977 978 979
### Signing and Signature Verification
```ts
/*
 * Generate and verify a signature using an SM2 key and return the result in a callback. 
 */
import huks from '@ohos.security.huks';
A
Annie_wang 已提交
980

A
Annie_wang 已提交
981 982 983 984 985 986 987 988 989
/*
 * Determine the key alias and encapsulate the key attribute set.
 */
let generateKeyAlias = 'sm2_Key';
let importKeyAlias = 'importKeyAlias';
let signVerifyInData = 'signVerifyInDataForTest';
let handle;
let exportKey;
let finishOutData;
A
Annie_wang 已提交
990

A
Annie_wang 已提交
991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014
/* Configure the parameter set used for generating the key. */
let generateKeyProperties = new Array();
generateKeyProperties[0] = {
    tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
    value: huks.HuksKeyAlg.HUKS_ALG_SM2,
}
generateKeyProperties[1] = {
    tag: huks.HuksTag.HUKS_TAG_PURPOSE,
    value:
    huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_SIGN |
    huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_VERIFY,
}
generateKeyProperties[2] = {
    tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
    value: huks.HuksKeySize.HUKS_SM2_KEY_SIZE_256,
}
generateKeyProperties[3] = {
    tag: huks.HuksTag.HUKS_TAG_DIGEST,
    value: huks.HuksKeyDigest.HUKS_DIGEST_SM3,
}
let genrateKeyOptions = {
    properties: generateKeyProperties,
    inData: new Uint8Array(new Array())
}
A
Annie_wang 已提交
1015

A
Annie_wang 已提交
1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038
/* Configure the parameter set used for signing. */
let signProperties = new Array();
signProperties[0] = {
    tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
    value: huks.HuksKeyAlg.HUKS_ALG_SM2,
}
signProperties[1] = {
    tag: huks.HuksTag.HUKS_TAG_PURPOSE,
    value:
    huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_SIGN
}
signProperties[2] = {
    tag: huks.HuksTag.HUKS_TAG_DIGEST,
    value: huks.HuksKeyDigest.HUKS_DIGEST_SM3,
}
signProperties[3] = {
    tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
    value: huks.HuksKeySize.HUKS_SM2_KEY_SIZE_256,
}
let signOptions = {
    properties: signProperties,
    inData: new Uint8Array(new Array())
}
A
Annie_wang 已提交
1039

A
Annie_wang 已提交
1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061
/* Configure the parameter set used for signature verification. */
let verifyProperties = new Array();
verifyProperties[0] = {
    tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
    value: huks.HuksKeyAlg.HUKS_ALG_SM2,
}
verifyProperties[1] = {
    tag: huks.HuksTag.HUKS_TAG_PURPOSE,
    value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_VERIFY
}
verifyProperties[2] = {
    tag: huks.HuksTag.HUKS_TAG_DIGEST,
    value: huks.HuksKeyDigest.HUKS_DIGEST_SM3,
}
verifyProperties[3] = {
    tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
    value: huks.HuksKeySize.HUKS_SM2_KEY_SIZE_256,
}
let verifyOptions = {
    properties: verifyProperties,
    inData: new Uint8Array(new Array())
}
A
Annie_wang 已提交
1062 1063 1064 1065

function StringToUint8Array(str) {
    let arr = [];
    for (let i = 0, j = str.length; i < j; ++i) {
A
Annie_wang 已提交
1066 1067 1068 1069
        arr.push(str.charCodeAt(i));
    }
    return new Uint8Array(arr);
}
A
Annie_wang 已提交
1070

A
Annie_wang 已提交
1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085
function generateKeyItem(keyAlias:string, huksOptions:huks.HuksOptions, throwObject) {
    return new Promise((resolve, reject) => {
        try {
            huks.generateKeyItem(keyAlias, huksOptions, function (error, data) {
                if (error) {
                    reject(error);
                } else {
                    resolve(data);
                }
            });
        } catch (error) {
            throwObject.isThrow = true;
            throw(error);
        }
    });
A
Annie_wang 已提交
1086 1087
}

A
Annie_wang 已提交
1088 1089
async function publicGenKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
    console.info(`enter callback generateKeyItem`);
A
Annie_wang 已提交
1090
    let throwObject = {isThrow: false};
A
Annie_wang 已提交
1091
    try {
A
Annie_wang 已提交
1092
        await generateKeyItem(keyAlias, huksOptions, throwObject)
A
Annie_wang 已提交
1093 1094 1095 1096
            .then((data) => {
                console.info(`callback: generateKeyItem success, data = ${JSON.stringify(data)}`);
            })
            .catch(error => {
A
Annie_wang 已提交
1097 1098 1099 1100 1101
                if (throwObject.isThrow) {
                    throw(error);
                } else {
                    console.error(`callback: generateKeyItem failed, code: ${error.code}, msg: ${error.message}`);
                }
A
Annie_wang 已提交
1102 1103 1104 1105 1106 1107
            });
    } catch (error) {
        console.error(`callback: generateKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
    }
}

A
Annie_wang 已提交
1108
function initSession(keyAlias:string, huksOptions:huks.HuksOptions, throwObject) : Promise<huks.HuksSessionHandle> {
A
Annie_wang 已提交
1109 1110
    return new Promise((resolve, reject) => {
        try {
A
Annie_wang 已提交
1111
            huks.initSession(keyAlias, huksOptions, function (error, data) {
A
Annie_wang 已提交
1112 1113 1114 1115 1116 1117 1118
                if (error) {
                    reject(error);
                } else {
                    resolve(data);
                }
            });
        } catch (error) {
A
Annie_wang 已提交
1119
            throwObject.isThrow = true;
A
Annie_wang 已提交
1120 1121 1122 1123 1124 1125
            throw(error);
        }
    });
}

async function publicInitFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
A
Annie_wang 已提交
1126 1127
    console.info(`enter callback doInit`);
    let throwObject = {isThrow: false};
A
Annie_wang 已提交
1128
    try {
A
Annie_wang 已提交
1129
        await initSession(keyAlias, huksOptions, throwObject)
A
Annie_wang 已提交
1130
            .then ((data) => {
A
Annie_wang 已提交
1131
                console.info(`callback: doInit success, data = ${JSON.stringify(data)}`);
A
Annie_wang 已提交
1132 1133
                handle = data.handle;
            })
A
Annie_wang 已提交
1134 1135 1136 1137 1138 1139
            .catch((error) => {
                if (throwObject.isThrow) {
                    throw(error);
                } else {
                    console.error(`callback: doInit failed, code: ${error.code}, msg: ${error.message}`);
                }
A
Annie_wang 已提交
1140 1141
            });
    } catch (error) {
A
Annie_wang 已提交
1142
        console.error(`callback: doInit input arg invalid, code: ${error.code}, msg: ${error.message}`);
A
Annie_wang 已提交
1143 1144 1145
    }
}

A
Annie_wang 已提交
1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162
function updateSession(handle:number, huksOptions:huks.HuksOptions, throwObject) : Promise<huks.HuksReturnResult> {
    return new Promise((resolve, reject) => {
        try {
            huks.updateSession(handle, huksOptions, function (error, data) {
                if (error) {
                    reject(error);
                } else {
                    resolve(data);
                }
            });
        } catch (error) {
            throwObject.isThrow = true;
            throw(error);
        }
    });
}

A
Annie_wang 已提交
1163 1164
async function publicUpdateFunc(handle:number, huksOptions:huks.HuksOptions) {
    console.info(`enter callback doUpdate`);
A
Annie_wang 已提交
1165
    let throwObject = {isThrow: false};
A
Annie_wang 已提交
1166
    try {
A
Annie_wang 已提交
1167
        await updateSession(handle, huksOptions, throwObject)
A
Annie_wang 已提交
1168 1169 1170 1171
            .then ((data) => {
                console.info(`callback: doUpdate success, data = ${JSON.stringify(data)}`);
            })
            .catch(error => {
A
Annie_wang 已提交
1172 1173 1174 1175 1176
                if (throwObject.isThrow) {
                    throw(error);
                } else {
                    console.error(`callback: doUpdate failed, code: ${error.code}, msg: ${error.message}`);
                }
A
Annie_wang 已提交
1177 1178 1179 1180 1181 1182
            });
    } catch (error) {
        console.error(`callback: doUpdate input arg invalid, code: ${error.code}, msg: ${error.message}`);
    }
}

A
Annie_wang 已提交
1183
function finishSession(handle:number, huksOptions:huks.HuksOptions, throwObject) : Promise<huks.HuksReturnResult> {
A
Annie_wang 已提交
1184 1185
    return new Promise((resolve, reject) => {
        try {
A
Annie_wang 已提交
1186
            huks.finishSession(handle, huksOptions, function (error, data) {
A
Annie_wang 已提交
1187 1188 1189 1190 1191 1192 1193
                if (error) {
                    reject(error);
                } else {
                    resolve(data);
                }
            });
        } catch (error) {
A
Annie_wang 已提交
1194
            throwObject.isThrow = true;
A
Annie_wang 已提交
1195 1196 1197 1198 1199 1200 1201
            throw(error);
        }
    });
}

async function publicFinishFunc(handle:number, huksOptions:huks.HuksOptions) {
    console.info(`enter callback doFinish`);
A
Annie_wang 已提交
1202
    let throwObject = {isThrow: false};
A
Annie_wang 已提交
1203
    try {
A
Annie_wang 已提交
1204
        await finishSession(handle, huksOptions, throwObject)
A
Annie_wang 已提交
1205
            .then ((data) => {
A
Annie_wang 已提交
1206
                finishOutData = data.outData;
A
Annie_wang 已提交
1207 1208 1209
                console.info(`callback: doFinish success, data = ${JSON.stringify(data)}`);
            })
            .catch(error => {
A
Annie_wang 已提交
1210 1211 1212 1213 1214
                if (throwObject.isThrow) {
                    throw(error);
                } else {
                    console.error(`callback: doFinish failed, code: ${error.code}, msg: ${error.message}`);
                }
A
Annie_wang 已提交
1215 1216 1217 1218 1219 1220
            });
    } catch (error) {
        console.error(`callback: doFinish input arg invalid, code: ${error.code}, msg: ${error.message}`);
    }
}

A
Annie_wang 已提交
1221
function exportKeyItem(keyAlias:string, huksOptions:huks.HuksOptions, throwObject) : Promise<huks.HuksReturnResult> {
A
Annie_wang 已提交
1222 1223
    return new Promise((resolve, reject) => {
        try {
A
Annie_wang 已提交
1224
            huks.exportKeyItem(keyAlias, huksOptions, function (error, data) {
A
Annie_wang 已提交
1225 1226 1227 1228 1229 1230 1231
                if (error) {
                    reject(error);
                } else {
                    resolve(data);
                }
            });
        } catch (error) {
A
Annie_wang 已提交
1232
            throwObject.isThrow = true;
A
Annie_wang 已提交
1233 1234 1235 1236 1237
            throw(error);
        }
    });
}

A
Annie_wang 已提交
1238 1239 1240
async function publicExportKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
    console.info(`enter callback export`);
    let throwObject = {isThrow: false};
A
Annie_wang 已提交
1241
    try {
A
Annie_wang 已提交
1242
        await exportKeyItem(keyAlias, huksOptions, throwObject)
A
Annie_wang 已提交
1243
            .then ((data) => {
A
Annie_wang 已提交
1244 1245
                console.info(`callback: exportKeyItem success, data = ${JSON.stringify(data)}`);
                exportKey = data.outData;
A
Annie_wang 已提交
1246 1247
            })
            .catch(error => {
A
Annie_wang 已提交
1248 1249 1250 1251 1252
                if (throwObject.isThrow) {
                    throw(error);
                } else {
                    console.error(`callback: exportKeyItem failed, code: ${error.code}, msg: ${error.message}`);
                }
A
Annie_wang 已提交
1253 1254
            });
    } catch (error) {
A
Annie_wang 已提交
1255
        console.error(`callback: exportKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
A
Annie_wang 已提交
1256 1257 1258
    }
}

A
Annie_wang 已提交
1259
function importKeyItem(keyAlias:string, huksOptions:huks.HuksOptions, throwObject) {
A
Annie_wang 已提交
1260 1261
    return new Promise((resolve, reject) => {
        try {
A
Annie_wang 已提交
1262
            huks.importKeyItem(keyAlias, huksOptions, function (error, data) {
A
Annie_wang 已提交
1263 1264 1265 1266 1267 1268 1269
                if (error) {
                    reject(error);
                } else {
                    resolve(data);
                }
            });
        } catch (error) {
A
Annie_wang 已提交
1270
            throwObject.isThrow = true;
A
Annie_wang 已提交
1271 1272 1273 1274
            throw(error);
        }
    });
}
A
Annie_wang 已提交
1275

A
Annie_wang 已提交
1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292
async function publicImportKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
    console.info(`enter promise importKeyItem`);
    let throwObject = {isThrow: false};
    try {
        await importKeyItem(keyAlias, huksOptions, throwObject)
            .then ((data) => {
                console.info(`callback: importKeyItem success, data = ${JSON.stringify(data)}`);
            })
            .catch(error => {
                if (throwObject.isThrow) {
                    throw(error);
                } else {
                    console.error(`callback: importKeyItem failed, code: ${error.code}, msg: ${error.message}`);
                }
            });
    } catch (error) {
        console.error(`callback: importKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
A
Annie_wang 已提交
1293
    }
A
Annie_wang 已提交
1294
}
A
Annie_wang 已提交
1295

A
Annie_wang 已提交
1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329
function deleteKeyItem(keyAlias:string, huksOptions:huks.HuksOptions, throwObject) {
    return new Promise((resolve, reject) => {
        try {
            huks.deleteKeyItem(keyAlias, huksOptions, function (error, data) {
                if (error) {
                    reject(error);
                } else {
                    resolve(data);
                }
            });
        } catch (error) {
            throwObject.isThrow = true;
            throw(error);
        }
    });
}

async function publicDeleteKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
    console.info(`enter callback deleteKeyItem`);
    let throwObject = {isThrow: false};
    try {
        await deleteKeyItem(keyAlias, huksOptions, throwObject)
            .then ((data) => {
                console.info(`callback: deleteKeyItem key success, data = ${JSON.stringify(data)}`);
            })
            .catch(error => {
                if (throwObject.isThrow) {
                    throw(error);
                } else {
                    console.error(`callback: deleteKeyItem failed, code: ${error.code}, msg: ${error.message}`);
                }
            });
    } catch (error) {
        console.error(`callback: deletKeeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
A
Annie_wang 已提交
1330
    }
A
Annie_wang 已提交
1331
}
A
Annie_wang 已提交
1332

A
Annie_wang 已提交
1333
async function testSm2SignVerify() {
A
Annie_wang 已提交
1334
    /* Generate a key. */
A
Annie_wang 已提交
1335
    await publicGenKeyFunc(generateKeyAlias, genrateKeyOptions);
A
Annie_wang 已提交
1336

A
Annie_wang 已提交
1337 1338 1339 1340
    /* Generate a signature. */
    let signHandle;
    let signFinishOutData;
    await publicInitFunc(generateKeyAlias, signOptions);
A
Annie_wang 已提交
1341

A
Annie_wang 已提交
1342 1343 1344
    signHandle = handle;
    signOptions.inData = StringToUint8Array(signVerifyInData)
    await publicUpdateFunc(signHandle, signOptions);
A
Annie_wang 已提交
1345

A
Annie_wang 已提交
1346 1347 1348
    signOptions.inData = new Uint8Array(new Array());
    await publicFinishFunc(signHandle, signOptions);
    signFinishOutData = finishOutData;
A
Annie_wang 已提交
1349

A
Annie_wang 已提交
1350 1351
    /* Export the key. */
    await publicExportKeyFunc(generateKeyAlias, genrateKeyOptions);
A
Annie_wang 已提交
1352

A
Annie_wang 已提交
1353 1354 1355
    /* Import the key. */
    verifyOptions.inData = exportKey;
    await publicImportKeyFunc(importKeyAlias, verifyOptions);
A
Annie_wang 已提交
1356

A
Annie_wang 已提交
1357 1358 1359
    /* Verify the signature. */
    let verifyHandle;
    await publicInitFunc(importKeyAlias, verifyOptions);
A
Annie_wang 已提交
1360

A
Annie_wang 已提交
1361
    verifyHandle = handle;
A
Annie_wang 已提交
1362

A
Annie_wang 已提交
1363 1364 1365 1366 1367 1368 1369 1370
    verifyOptions.inData = StringToUint8Array(signVerifyInData)
    await publicUpdateFunc(verifyHandle, verifyOptions);

    verifyOptions.inData = signFinishOutData;
    await publicFinishFunc(verifyHandle, verifyOptions);

    await publicDeleteKeyFunc(generateKeyAlias, genrateKeyOptions);
    await publicDeleteKeyFunc(importKeyAlias, genrateKeyOptions);
A
Annie_wang 已提交
1371 1372 1373
}
```

A
Annie_wang 已提交
1374
### Key Agreement
A
Annie_wang 已提交
1375
```ts
A
Annie_wang 已提交
1376 1377
/*
 * Perform key agreement using an X25519 256-bit TEMP key and return the result in a callback.
A
Annie_wang 已提交
1378
 */
A
Annie_wang 已提交
1379 1380
import huks from '@ohos.security.huks';

A
Annie_wang 已提交
1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477
/*
 * Determine the key alias and encapsulate the key attribute set.
 */
let srcKeyAliasFirst = "AgreeX25519KeyFirstAlias";
let srcKeyAliasSecond = "AgreeX25519KeySecondAlias";
let agreeX25519InData = 'AgreeX25519TestIndata';
let finishOutData;
let handle;
let exportKey;
let exportKeyFrist;
let exportKeySecond;

/* Configure the parameter set used for generating the key. */
let properties = new Array();
properties[0] = {
    tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
    value: huks.HuksKeyAlg.HUKS_ALG_X25519,
}
properties[1] = {
    tag: huks.HuksTag.HUKS_TAG_PURPOSE,
    value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_AGREE,
}
properties[2] = {
    tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
    value: huks.HuksKeySize.HUKS_CURVE25519_KEY_SIZE_256,
}
properties[3] = {
    tag: huks.HuksTag.HUKS_TAG_DIGEST,
    value: huks.HuksKeyDigest.HUKS_DIGEST_NONE,
}
properties[4] = {
    tag: huks.HuksTag.HUKS_TAG_PADDING,
    value: huks.HuksKeyPadding.HUKS_PADDING_NONE,
}
properties[5] = {
    tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE,
    value: huks.HuksCipherMode.HUKS_MODE_CBC,
}
let HuksOptions = {
    properties: properties,
    inData: new Uint8Array(new Array())
}

/* Configure parameters for the first key agreement. */
let finishProperties = new Array();
finishProperties[0] = {
    tag: huks.HuksTag.HUKS_TAG_KEY_STORAGE_FLAG,
    value: huks.HuksKeyStorageType.HUKS_STORAGE_TEMP,
}
finishProperties[1] = {
    tag: huks.HuksTag.HUKS_TAG_IS_KEY_ALIAS,
    value: true
}
finishProperties[2] = {
    tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
    value: huks.HuksKeyAlg.HUKS_ALG_AES,
}
finishProperties[3] = {
    tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
    value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_256,
}
finishProperties[4] = {
    tag: huks.HuksTag.HUKS_TAG_PURPOSE,
    value:
    huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT |
    huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT,
}
finishProperties[5] = {
    tag: huks.HuksTag.HUKS_TAG_DIGEST,
    value: huks.HuksKeyDigest.HUKS_DIGEST_NONE,
}
finishProperties[6] = {
    tag: huks.HuksTag.HUKS_TAG_KEY_ALIAS,
    value: StringToUint8Array(srcKeyAliasFirst+ 'final'),
}
finishProperties[7] = {
    tag: huks.HuksTag.HUKS_TAG_PADDING,
    value: huks.HuksKeyPadding.HUKS_PADDING_NONE,
}
finishProperties[8] = {
    tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE,
    value: huks.HuksCipherMode.HUKS_MODE_ECB,
}
let finishOptionsFrist = {
    properties: finishProperties,
    inData: StringToUint8Array(agreeX25519InData)
}
/* Configure parameters for the second key agreement. */
let finishOptionsSecond = {
    properties: finishProperties,
    inData: StringToUint8Array(agreeX25519InData)
}
finishOptionsSecond.properties.splice(6, 1, {
    tag: huks.HuksTag.HUKS_TAG_KEY_ALIAS,
    value: StringToUint8Array(srcKeyAliasSecond + 'final'),
})

A
Annie_wang 已提交
1478 1479 1480
function StringToUint8Array(str) {
    let arr = [];
    for (let i = 0, j = str.length; i < j; ++i) {
A
Annie_wang 已提交
1481 1482 1483 1484
        arr.push(str.charCodeAt(i));
    }
    return new Uint8Array(arr);
}
A
Annie_wang 已提交
1485

A
Annie_wang 已提交
1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500
function generateKeyItem(keyAlias:string, huksOptions:huks.HuksOptions, throwObject) {
    return new Promise((resolve, reject) => {
        try {
            huks.generateKeyItem(keyAlias, huksOptions, function (error, data) {
                if (error) {
                    reject(error);
                } else {
                    resolve(data);
                }
            });
        } catch (error) {
            throwObject.isThrow = true;
            throw(error);
        }
    });
A
Annie_wang 已提交
1501 1502
}

A
Annie_wang 已提交
1503 1504
async function publicGenKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
    console.info(`enter callback generateKeyItem`);
A
Annie_wang 已提交
1505
    let throwObject = {isThrow: false};
A
Annie_wang 已提交
1506
    try {
A
Annie_wang 已提交
1507
        await generateKeyItem(keyAlias, huksOptions, throwObject)
A
Annie_wang 已提交
1508 1509 1510 1511
            .then((data) => {
                console.info(`callback: generateKeyItem success, data = ${JSON.stringify(data)}`);
            })
            .catch(error => {
A
Annie_wang 已提交
1512 1513 1514 1515 1516
                if (throwObject.isThrow) {
                    throw(error);
                } else {
                    console.error(`callback: generateKeyItem failed, code: ${error.code}, msg: ${error.message}`);
                }
A
Annie_wang 已提交
1517 1518 1519 1520 1521 1522
            });
    } catch (error) {
        console.error(`callback: generateKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
    }
}

A
Annie_wang 已提交
1523
function initSession(keyAlias:string, huksOptions:huks.HuksOptions, throwObject) : Promise<huks.HuksSessionHandle> {
A
Annie_wang 已提交
1524 1525
    return new Promise((resolve, reject) => {
        try {
A
Annie_wang 已提交
1526
            huks.initSession(keyAlias, huksOptions, function (error, data) {
A
Annie_wang 已提交
1527 1528 1529 1530 1531 1532 1533
                if (error) {
                    reject(error);
                } else {
                    resolve(data);
                }
            });
        } catch (error) {
A
Annie_wang 已提交
1534
            throwObject.isThrow = true;
A
Annie_wang 已提交
1535 1536 1537 1538 1539 1540
            throw(error);
        }
    });
}

async function publicInitFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
A
Annie_wang 已提交
1541 1542
    console.info(`enter callback doInit`);
    let throwObject = {isThrow: false};
A
Annie_wang 已提交
1543
    try {
A
Annie_wang 已提交
1544
        await initSession(keyAlias, huksOptions, throwObject)
A
Annie_wang 已提交
1545
            .then ((data) => {
A
Annie_wang 已提交
1546
                console.info(`callback: doInit success, data = ${JSON.stringify(data)}`);
A
Annie_wang 已提交
1547 1548
                handle = data.handle;
            })
A
Annie_wang 已提交
1549 1550 1551 1552 1553 1554
            .catch((error) => {
                if (throwObject.isThrow) {
                    throw(error);
                } else {
                    console.error(`callback: doInit failed, code: ${error.code}, msg: ${error.message}`);
                }
A
Annie_wang 已提交
1555 1556
            });
    } catch (error) {
A
Annie_wang 已提交
1557
        console.error(`callback: doInit input arg invalid, code: ${error.code}, msg: ${error.message}`);
A
Annie_wang 已提交
1558 1559 1560
    }
}

A
Annie_wang 已提交
1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577
function updateSession(handle:number, huksOptions:huks.HuksOptions, throwObject) : Promise<huks.HuksReturnResult> {
    return new Promise((resolve, reject) => {
        try {
            huks.updateSession(handle, huksOptions, function (error, data) {
                if (error) {
                    reject(error);
                } else {
                    resolve(data);
                }
            });
        } catch (error) {
            throwObject.isThrow = true;
            throw(error);
        }
    });
}

A
Annie_wang 已提交
1578 1579
async function publicUpdateFunc(handle:number, huksOptions:huks.HuksOptions) {
    console.info(`enter callback doUpdate`);
A
Annie_wang 已提交
1580
    let throwObject = {isThrow: false};
A
Annie_wang 已提交
1581
    try {
A
Annie_wang 已提交
1582
        await updateSession(handle, huksOptions, throwObject)
A
Annie_wang 已提交
1583 1584 1585 1586
            .then ((data) => {
                console.info(`callback: doUpdate success, data = ${JSON.stringify(data)}`);
            })
            .catch(error => {
A
Annie_wang 已提交
1587 1588 1589 1590 1591
                if (throwObject.isThrow) {
                    throw(error);
                } else {
                    console.error(`callback: doUpdate failed, code: ${error.code}, msg: ${error.message}`);
                }
A
Annie_wang 已提交
1592 1593 1594 1595 1596 1597
            });
    } catch (error) {
        console.error(`callback: doUpdate input arg invalid, code: ${error.code}, msg: ${error.message}`);
    }
}

A
Annie_wang 已提交
1598
function finishSession(handle:number, huksOptions:huks.HuksOptions, throwObject) : Promise<huks.HuksReturnResult> {
A
Annie_wang 已提交
1599 1600
    return new Promise((resolve, reject) => {
        try {
A
Annie_wang 已提交
1601
            huks.finishSession(handle, huksOptions, function (error, data) {
A
Annie_wang 已提交
1602 1603 1604 1605 1606 1607 1608
                if (error) {
                    reject(error);
                } else {
                    resolve(data);
                }
            });
        } catch (error) {
A
Annie_wang 已提交
1609
            throwObject.isThrow = true;
A
Annie_wang 已提交
1610 1611 1612 1613 1614 1615 1616
            throw(error);
        }
    });
}

async function publicFinishFunc(handle:number, huksOptions:huks.HuksOptions) {
    console.info(`enter callback doFinish`);
A
Annie_wang 已提交
1617
    let throwObject = {isThrow: false};
A
Annie_wang 已提交
1618
    try {
A
Annie_wang 已提交
1619
        await finishSession(handle, huksOptions, throwObject)
A
Annie_wang 已提交
1620
            .then ((data) => {
A
Annie_wang 已提交
1621
                finishOutData = data.outData;
A
Annie_wang 已提交
1622 1623 1624
                console.info(`callback: doFinish success, data = ${JSON.stringify(data)}`);
            })
            .catch(error => {
A
Annie_wang 已提交
1625 1626 1627 1628 1629
                if (throwObject.isThrow) {
                    throw(error);
                } else {
                    console.error(`callback: doFinish failed, code: ${error.code}, msg: ${error.message}`);
                }
A
Annie_wang 已提交
1630 1631 1632 1633 1634 1635
            });
    } catch (error) {
        console.error(`callback: doFinish input arg invalid, code: ${error.code}, msg: ${error.message}`);
    }
}

A
Annie_wang 已提交
1636
function exportKeyItem(keyAlias:string, huksOptions:huks.HuksOptions, throwObject) : Promise<huks.HuksReturnResult> {
A
Annie_wang 已提交
1637 1638
    return new Promise((resolve, reject) => {
        try {
A
Annie_wang 已提交
1639
            huks.exportKeyItem(keyAlias, huksOptions, function (error, data) {
A
Annie_wang 已提交
1640 1641 1642 1643 1644 1645 1646
                if (error) {
                    reject(error);
                } else {
                    resolve(data);
                }
            });
        } catch (error) {
A
Annie_wang 已提交
1647
            throwObject.isThrow = true;
A
Annie_wang 已提交
1648 1649 1650 1651 1652
            throw(error);
        }
    });
}

A
Annie_wang 已提交
1653 1654 1655
async function publicExportKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
    console.info(`enter callback export`);
    let throwObject = {isThrow: false};
A
Annie_wang 已提交
1656
    try {
A
Annie_wang 已提交
1657
        await exportKeyItem(keyAlias, huksOptions, throwObject)
A
Annie_wang 已提交
1658
            .then ((data) => {
A
Annie_wang 已提交
1659 1660
                console.info(`callback: exportKeyItem success, data = ${JSON.stringify(data)}`);
                exportKey = data.outData;
A
Annie_wang 已提交
1661 1662
            })
            .catch(error => {
A
Annie_wang 已提交
1663 1664 1665 1666 1667
                if (throwObject.isThrow) {
                    throw(error);
                } else {
                    console.error(`callback: exportKeyItem failed, code: ${error.code}, msg: ${error.message}`);
                }
A
Annie_wang 已提交
1668 1669
            });
    } catch (error) {
A
Annie_wang 已提交
1670
        console.error(`callback: exportKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
A
Annie_wang 已提交
1671 1672 1673
    }
}

A
Annie_wang 已提交
1674
function deleteKeyItem(keyAlias:string, huksOptions:huks.HuksOptions, throwObject) {
A
Annie_wang 已提交
1675 1676 1677 1678 1679 1680 1681 1682 1683 1684
    return new Promise((resolve, reject) => {
        try {
            huks.deleteKeyItem(keyAlias, huksOptions, function (error, data) {
                if (error) {
                    reject(error);
                } else {
                    resolve(data);
                }
            });
        } catch (error) {
A
Annie_wang 已提交
1685
            throwObject.isThrow = true;
A
Annie_wang 已提交
1686 1687 1688 1689 1690
            throw(error);
        }
    });
}

A
Annie_wang 已提交
1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707
async function publicDeleteKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
    console.info(`enter callback deleteKeyItem`);
    let throwObject = {isThrow: false};
    try {
        await deleteKeyItem(keyAlias, huksOptions, throwObject)
            .then ((data) => {
                console.info(`callback: deleteKeyItem key success, data = ${JSON.stringify(data)}`);
            })
            .catch(error => {
                if (throwObject.isThrow) {
                    throw(error);
                } else {
                    console.error(`callback: deleteKeyItem failed, code: ${error.code}, msg: ${error.message}`);
                }
            });
    } catch (error) {
        console.error(`callback: deletKeeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
A
Annie_wang 已提交
1708
    }
A
Annie_wang 已提交
1709
}
A
Annie_wang 已提交
1710

A
Annie_wang 已提交
1711 1712 1713 1714
async function testAgree() {
    /* 1. Generate two keys and export them. */
    await publicGenKeyFunc(srcKeyAliasFirst, HuksOptions);
    await publicGenKeyFunc(srcKeyAliasSecond, HuksOptions);
A
Annie_wang 已提交
1715

A
Annie_wang 已提交
1716 1717 1718 1719
    await publicExportKeyFunc(srcKeyAliasFirst, HuksOptions);
    exportKeyFrist = exportKey;
    await publicExportKeyFunc(srcKeyAliasFirst, HuksOptions);
    exportKeySecond = exportKey;
A
Annie_wang 已提交
1720

A
Annie_wang 已提交
1721 1722 1723 1724 1725
    /* Perform key agreement for the first. */
    await publicInitFunc(srcKeyAliasFirst, HuksOptions);
    HuksOptions.inData = exportKeySecond;
    await publicUpdateFunc(handle, HuksOptions);
    await publicFinishFunc(handle, finishOptionsFrist);
A
Annie_wang 已提交
1726

A
Annie_wang 已提交
1727 1728 1729 1730 1731
    /* Perform key agreement for the second key. */
    await publicInitFunc(srcKeyAliasSecond, HuksOptions);
    HuksOptions.inData = exportKeyFrist;
    await publicUpdateFunc(handle, HuksOptions);
    await publicFinishFunc(handle, finishOptionsSecond);
A
Annie_wang 已提交
1732

A
Annie_wang 已提交
1733 1734
    await publicDeleteKeyFunc(srcKeyAliasFirst, HuksOptions);
    await publicDeleteKeyFunc(srcKeyAliasSecond, HuksOptions);
A
Annie_wang 已提交
1735 1736 1737
}
```

A
Annie_wang 已提交
1738 1739 1740 1741 1742 1743
### Key Derivation
```ts
/*
 * The following uses the Promise() operation of an HKDF256 key as an example.
 */
import huks from '@ohos.security.huks';
A
Annie_wang 已提交
1744

A
Annie_wang 已提交
1745 1746 1747 1748 1749 1750 1751 1752
/*
 * Determine the key alias and encapsulate the key attribute set.
 */
let srcKeyAlias = "hkdf_Key";
let deriveHkdfInData = "deriveHkdfTestIndata";
let handle;
let finishOutData;
let HuksKeyDeriveKeySize = 32;
A
Annie_wang 已提交
1753

A
Annie_wang 已提交
1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775
/* Configure the parameter set used for generating the key. */
let properties = new Array();
properties[0] = {
    tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
    value: huks.HuksKeyAlg.HUKS_ALG_AES,
}
properties[1] = {
    tag: huks.HuksTag.HUKS_TAG_PURPOSE,
    value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DERIVE,
}
properties[2] = {
    tag: huks.HuksTag.HUKS_TAG_DIGEST,
    value: huks.HuksKeyDigest.HUKS_DIGEST_SHA256,
}
properties[3] = {
    tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
    value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_128,
}
let huksOptions = {
    properties: properties,
    inData: new Uint8Array(new Array())
}
A
Annie_wang 已提交
1776

A
Annie_wang 已提交
1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798
/* Configure the parameter set used for init(). */
let initProperties = new Array();
initProperties[0] = {
    tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
    value: huks.HuksKeyAlg.HUKS_ALG_HKDF,
}
initProperties[1] = {
    tag: huks.HuksTag.HUKS_TAG_PURPOSE,
    value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DERIVE,
}
initProperties[2] = {
    tag: huks.HuksTag.HUKS_TAG_DIGEST,
    value: huks.HuksKeyDigest.HUKS_DIGEST_SHA256,
}
initProperties[3] = {
    tag: huks.HuksTag.HUKS_TAG_DERIVE_KEY_SIZE,
    value: HuksKeyDeriveKeySize,
}
let initOptions = {
    properties: initProperties,
    inData: new Uint8Array(new Array())
}
A
Annie_wang 已提交
1799

A
Annie_wang 已提交
1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843
/* Configure the parameter set used for finish(). */
let finishProperties = new Array();
finishProperties[0] = {
    tag: huks.HuksTag.HUKS_TAG_KEY_STORAGE_FLAG,
    value: huks.HuksKeyStorageType.HUKS_STORAGE_PERSISTENT,
}
finishProperties[1] = {
    tag: huks.HuksTag.HUKS_TAG_IS_KEY_ALIAS,
    value: true,
}
finishProperties[2] = {
    tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
    value: huks.HuksKeyAlg.HUKS_ALG_AES,
}
finishProperties[3] = {
    tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
    value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_256,
}
finishProperties[4] = {
    tag: huks.HuksTag.HUKS_TAG_PURPOSE,
    value:
    huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT |
    huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT,
}
finishProperties[5] = {
    tag: huks.HuksTag.HUKS_TAG_DIGEST,
    value: huks.HuksKeyDigest.HUKS_DIGEST_NONE,
}
finishProperties[6] = {
    tag: huks.HuksTag.HUKS_TAG_KEY_ALIAS,
    value: StringToUint8Array(srcKeyAlias),
}
finishProperties[7] = {
    tag: huks.HuksTag.HUKS_TAG_PADDING,
    value: huks.HuksKeyPadding.HUKS_PADDING_NONE,
}
finishProperties[8] = {
    tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE,
    value: huks.HuksCipherMode.HUKS_MODE_ECB,
}
let finishOptions = {
    properties: finishProperties,
    inData: new Uint8Array(new Array())
}
A
Annie_wang 已提交
1844 1845 1846 1847

function StringToUint8Array(str) {
    let arr = [];
    for (let i = 0, j = str.length; i < j; ++i) {
A
Annie_wang 已提交
1848 1849 1850 1851 1852
        arr.push(str.charCodeAt(i));
    }
    return new Uint8Array(arr);
}

A
Annie_wang 已提交
1853
function generateKeyItem(keyAlias:string, huksOptions:huks.HuksOptions, throwObject) {
A
Annie_wang 已提交
1854 1855 1856 1857 1858 1859 1860 1861 1862 1863
    return new Promise((resolve, reject) => {
        try {
            huks.generateKeyItem(keyAlias, huksOptions, function (error, data) {
                if (error) {
                    reject(error);
                } else {
                    resolve(data);
                }
            });
        } catch (error) {
A
Annie_wang 已提交
1864
            throwObject.isThrow = true;
A
Annie_wang 已提交
1865 1866 1867 1868
            throw(error);
        }
    });
}
A
Annie_wang 已提交
1869

A
Annie_wang 已提交
1870 1871 1872
async function publicGenKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
    console.info(`enter callback generateKeyItem`);
    let throwObject = {isThrow: false};
A
Annie_wang 已提交
1873
    try {
A
Annie_wang 已提交
1874 1875 1876
        await generateKeyItem(keyAlias, huksOptions, throwObject)
            .then((data) => {
                console.info(`callback: generateKeyItem success, data = ${JSON.stringify(data)}`);
A
Annie_wang 已提交
1877
            })
A
Annie_wang 已提交
1878 1879 1880 1881 1882 1883
            .catch(error => {
                if (throwObject.isThrow) {
                    throw(error);
                } else {
                    console.error(`callback: generateKeyItem failed, code: ${error.code}, msg: ${error.message}`);
                }
A
Annie_wang 已提交
1884 1885
            });
    } catch (error) {
A
Annie_wang 已提交
1886
        console.error(`callback: generateKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
A
Annie_wang 已提交
1887
    }
A
Annie_wang 已提交
1888
}
A
Annie_wang 已提交
1889

A
Annie_wang 已提交
1890
function initSession(keyAlias:string, huksOptions:huks.HuksOptions, throwObject) : Promise<huks.HuksSessionHandle> {
A
Annie_wang 已提交
1891 1892 1893 1894 1895 1896 1897 1898 1899 1900
    return new Promise((resolve, reject) => {
        try {
            huks.initSession(keyAlias, huksOptions, function (error, data) {
                if (error) {
                    reject(error);
                } else {
                    resolve(data);
                }
            });
        } catch (error) {
A
Annie_wang 已提交
1901
            throwObject.isThrow = true;
A
Annie_wang 已提交
1902 1903
            throw(error);
        }
A
Annie_wang 已提交
1904
    });
A
Annie_wang 已提交
1905
}
A
Annie_wang 已提交
1906

A
Annie_wang 已提交
1907 1908 1909
async function publicInitFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
    console.info(`enter callback doInit`);
    let throwObject = {isThrow: false};
A
Annie_wang 已提交
1910
    try {
A
Annie_wang 已提交
1911
        await initSession(keyAlias, huksOptions, throwObject)
A
Annie_wang 已提交
1912
            .then ((data) => {
A
Annie_wang 已提交
1913 1914
                console.info(`callback: doInit success, data = ${JSON.stringify(data)}`);
                handle = data.handle;
A
Annie_wang 已提交
1915
            })
A
Annie_wang 已提交
1916 1917 1918 1919 1920 1921
            .catch((error) => {
                if (throwObject.isThrow) {
                    throw(error);
                } else {
                    console.error(`callback: doInit failed, code: ${error.code}, msg: ${error.message}`);
                }
A
Annie_wang 已提交
1922 1923
            });
    } catch (error) {
A
Annie_wang 已提交
1924
        console.error(`callback: doInit input arg invalid, code: ${error.code}, msg: ${error.message}`);
A
Annie_wang 已提交
1925 1926 1927
    }
}

A
Annie_wang 已提交
1928
function updateSession(handle:number, huksOptions:huks.HuksOptions, throwObject) : Promise<huks.HuksReturnResult> {
A
Annie_wang 已提交
1929 1930 1931 1932 1933 1934 1935 1936 1937 1938
    return new Promise((resolve, reject) => {
        try {
            huks.updateSession(handle, huksOptions, function (error, data) {
                if (error) {
                    reject(error);
                } else {
                    resolve(data);
                }
            });
        } catch (error) {
A
Annie_wang 已提交
1939
            throwObject.isThrow = true;
A
Annie_wang 已提交
1940 1941
            throw(error);
        }
A
Annie_wang 已提交
1942
    });
A
Annie_wang 已提交
1943 1944
}

A
Annie_wang 已提交
1945 1946 1947
async function publicUpdateFunc(handle:number, huksOptions:huks.HuksOptions) {
    console.info(`enter callback doUpdate`);
    let throwObject = {isThrow: false};
A
Annie_wang 已提交
1948
    try {
A
Annie_wang 已提交
1949
        await updateSession(handle, huksOptions, throwObject)
A
Annie_wang 已提交
1950
            .then ((data) => {
A
Annie_wang 已提交
1951
                console.info(`callback: doUpdate success, data = ${JSON.stringify(data)}`);
A
Annie_wang 已提交
1952 1953
            })
            .catch(error => {
A
Annie_wang 已提交
1954 1955 1956 1957 1958
                if (throwObject.isThrow) {
                    throw(error);
                } else {
                    console.error(`callback: doUpdate failed, code: ${error.code}, msg: ${error.message}`);
                }
A
Annie_wang 已提交
1959 1960
            });
    } catch (error) {
A
Annie_wang 已提交
1961
        console.error(`callback: doUpdate input arg invalid, code: ${error.code}, msg: ${error.message}`);
A
Annie_wang 已提交
1962 1963 1964
    }
}

A
Annie_wang 已提交
1965
function finishSession(handle:number, huksOptions:huks.HuksOptions, throwObject) : Promise<huks.HuksReturnResult> {
A
Annie_wang 已提交
1966 1967 1968 1969 1970 1971 1972 1973 1974 1975
    return new Promise((resolve, reject) => {
        try {
            huks.finishSession(handle, huksOptions, function (error, data) {
                if (error) {
                    reject(error);
                } else {
                    resolve(data);
                }
            });
        } catch (error) {
A
Annie_wang 已提交
1976
            throwObject.isThrow = true;
A
Annie_wang 已提交
1977 1978
            throw(error);
        }
A
Annie_wang 已提交
1979
    });
A
Annie_wang 已提交
1980 1981
}

A
Annie_wang 已提交
1982 1983 1984
async function publicFinishFunc(handle:number, huksOptions:huks.HuksOptions) {
    console.info(`enter callback doFinish`);
    let throwObject = {isThrow: false};
A
Annie_wang 已提交
1985
    try {
A
Annie_wang 已提交
1986
        await finishSession(handle, huksOptions, throwObject)
A
Annie_wang 已提交
1987
            .then ((data) => {
A
Annie_wang 已提交
1988 1989
                finishOutData = data.outData;
                console.info(`callback: doFinish success, data = ${JSON.stringify(data)}`);
A
Annie_wang 已提交
1990 1991
            })
            .catch(error => {
A
Annie_wang 已提交
1992 1993
                if (throwObject.isThrow) {
                    throw(error);
A
Annie_wang 已提交
1994
                } else {
A
Annie_wang 已提交
1995
                    console.error(`callback: doFinish failed, code: ${error.code}, msg: ${error.message}`);
A
Annie_wang 已提交
1996 1997 1998
                }
            });
    } catch (error) {
A
Annie_wang 已提交
1999
        console.error(`callback: doFinish input arg invalid, code: ${error.code}, msg: ${error.message}`);
A
Annie_wang 已提交
2000 2001 2002
    }
}

A
Annie_wang 已提交
2003
function deleteKeyItem(keyAlias:string, huksOptions:huks.HuksOptions, throwObject) {
A
Annie_wang 已提交
2004 2005
    return new Promise((resolve, reject) => {
        try {
A
Annie_wang 已提交
2006
            huks.deleteKeyItem(keyAlias, huksOptions, function (error, data) {
A
Annie_wang 已提交
2007 2008 2009 2010 2011 2012 2013
                if (error) {
                    reject(error);
                } else {
                    resolve(data);
                }
            });
        } catch (error) {
A
Annie_wang 已提交
2014
            throwObject.isThrow = true;
A
Annie_wang 已提交
2015 2016
            throw(error);
        }
A
Annie_wang 已提交
2017
    });
A
Annie_wang 已提交
2018 2019 2020 2021
}

async function publicDeleteKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
    console.info(`enter callback deleteKeyItem`);
A
Annie_wang 已提交
2022
    let throwObject = {isThrow: false};
A
Annie_wang 已提交
2023
    try {
A
Annie_wang 已提交
2024
        await deleteKeyItem(keyAlias, huksOptions, throwObject)
A
Annie_wang 已提交
2025 2026 2027 2028
            .then ((data) => {
                console.info(`callback: deleteKeyItem key success, data = ${JSON.stringify(data)}`);
            })
            .catch(error => {
A
Annie_wang 已提交
2029 2030 2031 2032 2033
                if (throwObject.isThrow) {
                    throw(error);
                } else {
                    console.error(`callback: deleteKeyItem failed, code: ${error.code}, msg: ${error.message}`);
                }
A
Annie_wang 已提交
2034 2035
            });
    } catch (error) {
A
Annie_wang 已提交
2036
        console.error(`callback: deletKeeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
A
Annie_wang 已提交
2037 2038 2039
    }
}

A
Annie_wang 已提交
2040 2041 2042
async function testDerive() {
    /* Generate a key. */
    await publicGenKeyFunc(srcKeyAlias, huksOptions);
A
Annie_wang 已提交
2043

A
Annie_wang 已提交
2044 2045
    /* Derive a key. */
    await publicInitFunc(srcKeyAlias, initOptions);
A
Annie_wang 已提交
2046

A
Annie_wang 已提交
2047 2048 2049 2050 2051
    initOptions.inData = StringToUint8Array(deriveHkdfInData);
    await publicUpdateFunc(handle, initOptions);
    await publicFinishFunc(handle, finishOptions);

    await publicDeleteKeyFunc(srcKeyAlias, huksOptions);
A
Annie_wang 已提交
2052
}
A
Annie_wang 已提交
2053
```
A
Annie_wang 已提交
2054

A
Annie_wang 已提交
2055
## Key Access Control
A
Annie_wang 已提交
2056

A
Annie_wang 已提交
2057
The HUKS provides comprehensive key access control to prevent unauthorized access.
A
Annie_wang 已提交
2058

A
Annie_wang 已提交
2059 2060 2061
Services can access only their own keys, that is, the keys generated or imported through HUKS.
In addition, the HUKS supports user identity authentication for security-sensitive services. Users can use the service keys only after the authentication (PIN or biometric authentication) is successful.
The HUKS also restricts the key usage. For example, the AES keys can only be used for encryption and decryption, and the RSA keys can only be used for signing and signature verification.
A
Annie_wang 已提交
2062

A
Annie_wang 已提交
2063
**<font size=5>User Identity Authentication</font>**
A
Annie_wang 已提交
2064

A
Annie_wang 已提交
2065
When generating or importing a key, you can enable user identity authentication for the key use. You can specify a subset of credentials (lock screen password, fingerprint, and face) for user identity authentication. After a key is generated or imported, unauthorized key access can be prevented even if the application process is attacked. Key access control applies to security-sensitive scenarios, such as password-free login, password-free payment, and automatic password filling.
A
Annie_wang 已提交
2066

A
Annie_wang 已提交
2067 2068 2069
In addition to user identity authentication, the authorized key access type (key expiration condition) must be either of the following types:
- Invalidate the key when the screen lock password is cleared.<br>This type takes effect only when a screen lock password has been set. If the screen lock password is cleared, the key becomes invalid permanently. The key will not be invalidated if the screen lock password is modified. Use this type for user-related data protection or access based on screen lock passwords.
- Invalidate the key when new biometric enrollments are added.<br>This type takes effect only when at least one biometric feature (such as fingerprint) has been enrolled. The key becomes invalid permanently once a new biometric feature is enrolled. The key will not be invalidated if the biometric feature is deleted. You can use this type for scenarios, such as password-free login or payment.
A
Annie_wang 已提交
2070

A
Annie_wang 已提交
2071
To ensure the validity of the user authentication result, the HUKS supports challenge value verification. Before user identity authentication, obtain the challenge (in the [HuksSessionHandle](../reference/apis/js-apis-huks.md#hukssessionhandle9) returned by [huks.initSession()](../reference/apis/js-apis-huks.md#huksinitsession9)) from the HUKS and pass in the challenge in [userIAM_userAuth.getAuthInstance](../reference/apis/js-apis-useriam-userauth.md#authinstance9). The challenge value of the authentication token is then verified during key operations.
A
Annie_wang 已提交
2072

A
Annie_wang 已提交
2073
**How to Develop**
A
Annie_wang 已提交
2074

A
Annie_wang 已提交
2075
If secondary user identity authentication is enabled for a key, initialize the key session and obtain the challenge value. Then, pass the challenge value to **userIAM_userAuth.getAuthInstance()** for user identity authentication. After the authentication is successful, an authentication token is obtained. The authentication token can be used to perform key operations.
A
Annie_wang 已提交
2076

A
Annie_wang 已提交
2077
![huks_key_user_auth_work_flow](./figures/huks_key_user_auth_work_flow.png)
A
Annie_wang 已提交
2078

A
Annie_wang 已提交
2079
**Available APIs**
A
Annie_wang 已提交
2080

A
Annie_wang 已提交
2081
1. [HuksUserAuthType](../reference/apis/js-apis-huks.md#huksuserauthtype9), [HuksAuthAccessType](../reference/apis/js-apis-huks.md#huksauthaccesstype9), and [HuksChallengeType](../reference/apis/js-apis-huks.md#hukschallengetype9) in the key attribute set are mandatory for key generation/import.
A
Annie_wang 已提交
2082

A
Annie_wang 已提交
2083 2084 2085 2086 2087
	**Table 3** User authentication types
	
	| Name           | Value | Description                     |
	| ------------------------------- |---|------------------------ |
	| HUKS_USER_AUTH_TYPE_FINGERPRINT |0x0001  | Fingerprint authentication. |
A
Annie_wang 已提交
2088 2089
	| HUKS_USER_AUTH_TYPE_FACE     |0x0002   | Facial authentication.|
	| HUKS_USER_AUTH_TYPE_PIN      |0x0004  | PIN authentication. |
A
Annie_wang 已提交
2090 2091 2092 2093 2094
	
	> **NOTE**
	>
	> You can specify any or a combination of the three authentication types. 
	
A
Annie_wang 已提交
2095

A
Annie_wang 已提交
2096 2097 2098 2099 2100 2101
	**Table 4** Secure access types
	
	| Name                                   | Value  | Description            |
	| --------------------------------------- | ---- | ------------------------------------------------ |
	| HUKS_AUTH_ACCESS_INVALID_CLEAR_PASSWORD | 1    | Invalidates the key after the screen lock password is cleared.      |
	| HUKS_AUTH_ACCESS_INVALID_NEW_BIO_ENROLL | 2    | Invalidates the key after a biometric enrollment is added. The user authentication types must include the biometric authentication.|
A
Annie_wang 已提交
2102

A
Annie_wang 已提交
2103
	> **NOTE**
A
Annie_wang 已提交
2104 2105
	>
	> **HUKS_AUTH_ACCESS_INVALID_CLEAR_PASSWORD** and **HUKS_AUTH_ACCESS_INVALID_NEW_BIO_ENROLL** are mutually exclusive.
A
Annie_wang 已提交
2106

A
Annie_wang 已提交
2107
	**Table 5** Challenge types
A
Annie_wang 已提交
2108

A
Annie_wang 已提交
2109 2110 2111 2112 2113
	| Name                           | Value  | Description                       |
	| ------------------------------- | ---- | ------------------------------ |
	| HUKS_CHALLENGE_TYPE_NORMAL | 0    | Normal challenge, which requires an independent user authentication for each use of the key.|
	| HUKS_CHALLENGE_TYPE_CUSTOM        | 1    | Custom challenge, which supports only one user authentication for multiple keys.|
	| HUKS_CHALLENGE_TYPE_NONE         | 2    | No challenge is required during user authentication.|
A
Annie_wang 已提交
2114

A
Annie_wang 已提交
2115 2116 2117 2118 2119
	> **NOTICE**
	>
	> The three challenge types are mutually exclusive.
	>
	> If the challenge type is **HUKS_CHALLENGE_TYPE_NONE**, no challenge is required. However, the key can be accessed only within a specified time period (set by **HUKS_TAG_AUTH_TIMEOUT**) after a successful authentication. The maximum value of **HUKS_TAG_AUTH_TIMEOUT** is 60 seconds.
A
Annie_wang 已提交
2120

A
Annie_wang 已提交
2121

A
Annie_wang 已提交
2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132
2. To use a key, initialize the key session, and determine whether a challenge is required based on the challenge type specified when the key is generated or imported.
	
	**Table 6** APIs for using a key
	
	| API           | Description                          |
	|-------------- | ------------------------------------ |
	| initSession(keyAlias: string, options: HuksOptions, callback: AsyncCallback\<HuksSessionHandle>) : void |Initializes the key session and obtains the challenge value.|
	| updateSession(handle: number, options: HuksOptions, token: Uint8Array, callback: AsyncCallback\<HuksReturnResult>) : void| Operates data by segment and passes the authentication token.|
	| finishSession(handle: number, options: HuksOptions, token: Uint8Array, callback: AsyncCallback\<HuksReturnResult>) : void | Finalizes the key session.|
   
   
A
Annie_wang 已提交
2133

A
Annie_wang 已提交
2134
**How to Develop**
A
Annie_wang 已提交
2135
	
A
Annie_wang 已提交
2136

A
Annie_wang 已提交
2137
1. Generate a key and specify user authentication attributes.
A
Annie_wang 已提交
2138

A
Annie_wang 已提交
2139 2140 2141
```ts
import huks from '@ohos.security.huks';

A
Annie_wang 已提交
2142 2143 2144 2145 2146 2147 2148 2149
/*
 * Determine the key alias and encapsulate the key attribute set.
 */
let keyAlias = 'dh_key_fingerprint_access';
let properties = new Array();
properties[0] = {
  tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
  value: huks.HuksKeyAlg.HUKS_ALG_SM4,
A
Annie_wang 已提交
2150
}
A
Annie_wang 已提交
2151 2152 2153
properties[1] = {
  tag: huks.HuksTag.HUKS_TAG_PURPOSE,
  value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT | huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT,
A
Annie_wang 已提交
2154
}
A
Annie_wang 已提交
2155 2156 2157
properties[2] = {
  tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
  value: huks.HuksKeySize.HUKS_SM4_KEY_SIZE_128,
A
Annie_wang 已提交
2158
}
A
Annie_wang 已提交
2159 2160 2161
properties[3] = {
  tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE,
  value: huks.HuksCipherMode.HUKS_MODE_CBC,
A
Annie_wang 已提交
2162
}
A
Annie_wang 已提交
2163 2164 2165
properties[4] = {
  tag: huks.HuksTag.HUKS_TAG_PADDING,
  value: huks.HuksKeyPadding.HUKS_PADDING_NONE,
A
Annie_wang 已提交
2166
}
A
Annie_wang 已提交
2167 2168 2169 2170
// Enable fingerprint authentication.
properties[5] = {
  tag: huks.HuksTag.HUKS_TAG_USER_AUTH_TYPE,
  value: huks.HuksUserAuthType.HUKS_USER_AUTH_TYPE_FINGERPRINT
A
Annie_wang 已提交
2171
}
A
Annie_wang 已提交
2172 2173 2174 2175
// Set the key expiration type. Invalidate the key when a new biometric feature (fingerprint) is enrolled.
properties[6] = {
  tag: huks.HuksTag.HUKS_TAG_KEY_AUTH_ACCESS_TYPE,
  value: huks.HuksAuthAccessType.HUKS_AUTH_ACCESS_INVALID_NEW_BIO_ENROLL
A
Annie_wang 已提交
2176
}
A
Annie_wang 已提交
2177 2178 2179 2180
// Use the default challenge type.
properties[7] = {
  tag: huks.HuksTag.HUKS_TAG_CHALLENGE_TYPE,
  value: huks.HuksChallengeType.HUKS_CHALLENGE_TYPE_NORMAL
A
Annie_wang 已提交
2181
}
A
Annie_wang 已提交
2182 2183 2184
let huksOptions = {
  properties: properties,
  inData: new Uint8Array(new Array())
A
Annie_wang 已提交
2185 2186
}

A
Annie_wang 已提交
2187 2188 2189 2190 2191
/*
 * Generate a key.
 */
function generateKeyItem(keyAlias:string, huksOptions:huks.HuksOptions, throwObject) {
  return new Promise((resolve, reject) => {
A
Annie_wang 已提交
2192
    try {
A
Annie_wang 已提交
2193 2194 2195 2196 2197
      huks.generateKeyItem(keyAlias, huksOptions, function (error, data) {
        if (error) {
          reject(error);
        } else {
          resolve(data);
A
Annie_wang 已提交
2198
        }
A
Annie_wang 已提交
2199 2200 2201 2202
      });
    } catch (error) {
      throwObject.isThrow = true;
      throw(error);
A
Annie_wang 已提交
2203
    }
A
Annie_wang 已提交
2204
  });
A
Annie_wang 已提交
2205 2206
}

A
Annie_wang 已提交
2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225
async function publicGenKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
  console.info(`enter callback generateKeyItem`);
  let throwObject = {isThrow: false};
  try {
    await generateKeyItem(keyAlias, huksOptions, throwObject)
      .then((data) => {
        console.info(`callback: generateKeyItem success, data = ${JSON.stringify(data)}`);
      })
      .catch(error => {
        if (throwObject.isThrow) {
          throw(error);
        } else {
          console.error(`callback: generateKeyItem failed, code: ${error.code}, msg: ${error.message}`);
        }
      });
  } catch (error) {
    console.error(`callback: generateKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
  }
}
A
Annie_wang 已提交
2226

A
Annie_wang 已提交
2227 2228 2229 2230
async function TestGenKeyForFingerprintAccessControl() {
  await publicGenKeyFunc(keyAlias, huksOptions);
}
```
A
Annie_wang 已提交
2231 2232


A
Annie_wang 已提交
2233
2. Initialize the key session to obtain a challenge, and initiate fingerprint authentication to obtain an authentication token.
A
Annie_wang 已提交
2234
```ts
A
Annie_wang 已提交
2235
import huks from '@ohos.security.huks';
A
Annie_wang 已提交
2236
import userIAM_userAuth from '@ohos.userIAM.userAuth';
A
Annie_wang 已提交
2237

A
Annie_wang 已提交
2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272
/*
 * Determine the key alias and encapsulate the key attribute set.
 */
let srcKeyAlias = 'sm4_key_fingerprint_access';
let handle;
let challenge;
let fingerAuthToken;
let authType = userIAM_userAuth.UserAuthType.FINGERPRINT;
let authTrustLevel = userIAM_userAuth.AuthTrustLevel.ATL1;

/* Configure the key generation parameter set and key encryption parameter set. */
let properties = new Array();
properties[0] = {
  tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
  value: huks.HuksKeyAlg.HUKS_ALG_SM4,
}
properties[1] = {
  tag: huks.HuksTag.HUKS_TAG_PURPOSE,
  value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT | huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT,
}
properties[2] = {
  tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
  value: huks.HuksKeySize.HUKS_SM4_KEY_SIZE_128,
}
properties[3] = {
  tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE,
  value: huks.HuksCipherMode.HUKS_MODE_CBC,
}
properties[4] = {
  tag: huks.HuksTag.HUKS_TAG_PADDING,
  value: huks.HuksKeyPadding.HUKS_PADDING_NONE,
}
let huksOptions = {
  properties: properties,
  inData: new Uint8Array(new Array())
A
Annie_wang 已提交
2273 2274
}

A
Annie_wang 已提交
2275 2276
function initSession(keyAlias:string, huksOptions:huks.HuksOptions, throwObject) : Promise<huks.HuksSessionHandle> {
  return new Promise((resolve, reject) => {
A
Annie_wang 已提交
2277
    try {
A
Annie_wang 已提交
2278 2279 2280 2281 2282 2283 2284
      huks.initSession(keyAlias, huksOptions, function (error, data) {
        if (error) {
          reject(error);
        } else {
          resolve(data);
        }
      });
A
Annie_wang 已提交
2285
    } catch (error) {
A
Annie_wang 已提交
2286 2287
      throwObject.isThrow = true;
      throw(error);
A
Annie_wang 已提交
2288
    }
A
Annie_wang 已提交
2289
  });
A
Annie_wang 已提交
2290 2291
}

A
Annie_wang 已提交
2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306
async function publicInitFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
  console.info(`enter callback doInit`);
  let throwObject = {isThrow: false};
  try {
    await initSession(keyAlias, huksOptions, throwObject)
      .then ((data) => {
        console.info(`callback: doInit success, data = ${JSON.stringify(data)}`);
        handle = data.handle;
        challenge = data.challenge;
      })
      .catch((error) => {
        if (throwObject.isThrow) {
          throw(error);
        } else {
          console.error(`callback: doInit failed, code: ${error.code}, msg: ${error.message}`);
A
Annie_wang 已提交
2307
        }
A
Annie_wang 已提交
2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330
      });
  } catch (error) {
    console.error(`callback: doInit input arg invalid, code: ${error.code}, msg: ${error.message}`);
  }
}

function userIAMAuthFinger(huksChallenge:Uint8Array) {
  // Obtain an authentication object.
  let auth;
  try {
    auth = userIAM_userAuth.getAuthInstance(huksChallenge, authType, authTrustLevel);
    console.log("get auth instance success");
  } catch (error) {
    console.log("get auth instance failed" + error);
  }

  // Subscribe to the authentication result.
  try {
    auth.on("result", {
      callback: (result: userIAM_userAuth.AuthResultInfo) => {
        /* The authentication is successful, and the authentication token is obtained. */
        fingerAuthToken = result.token;
      }
A
Annie_wang 已提交
2331
    });
A
Annie_wang 已提交
2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350
    console.log("subscribe authentication event success");
  } catch (error) {
    console.log("subscribe authentication event failed " + error);
  }

  // Start user authentication.
  try {
    auth.start();
    console.info("authV9 start auth success");
  } catch (error) {
    console.info("authV9 start auth failed, error = " + error);
  }
}

async function testInitAndAuthFinger() {
  /* Initialize the key session to obtain a challenge. */
  await publicInitFunc(srcKeyAlias, huksOptions);
  /* Invoke userIAM to perform user identity authentication. */
  userIAMAuthFinger(challenge);
A
Annie_wang 已提交
2351
}
A
Annie_wang 已提交
2352
```
A
Annie_wang 已提交
2353

A
Annie_wang 已提交
2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400
3. Pass in the authentication token to perform data operations.
```ts
/*
 * The following uses an SM4 128-bit key and callback-based APIs as an example.
 */
import huks from '@ohos.security.huks';

/*
 * Determine the key alias and encapsulate the key attribute set.
 */
let srcKeyAlias = 'sm4_key_fingerprint_access';
let IV = '1234567890123456';
let cipherInData = 'Hks_SM4_Cipher_Test_101010101010101010110_string';
let handle;
let fingerAuthToken;
let updateResult = new Array();
let finishOutData;

/* Configure the key generation parameter set and key encryption parameter set. */
let propertiesEncrypt = new Array();
propertiesEncrypt[0] = {
  tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
  value: huks.HuksKeyAlg.HUKS_ALG_SM4,
}
propertiesEncrypt[1] = {
  tag: huks.HuksTag.HUKS_TAG_PURPOSE,
  value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT,
}
propertiesEncrypt[2] = {
  tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
  value: huks.HuksKeySize.HUKS_SM4_KEY_SIZE_128,
}
propertiesEncrypt[3] = {
  tag: huks.HuksTag.HUKS_TAG_PADDING,
  value: huks.HuksKeyPadding.HUKS_PADDING_NONE,
}
propertiesEncrypt[4] = {
  tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE,
  value: huks.HuksCipherMode.HUKS_MODE_CBC,
}
propertiesEncrypt[5] = {
  tag: huks.HuksTag.HUKS_TAG_IV,
  value: StringToUint8Array(IV),
}
let encryptOptions = {
  properties: propertiesEncrypt,
  inData: new Uint8Array(new Array())
A
Annie_wang 已提交
2401 2402
}

A
Annie_wang 已提交
2403 2404 2405 2406 2407 2408
function StringToUint8Array(str) {
  let arr = [];
  for (let i = 0, j = str.length; i < j; ++i) {
    arr.push(str.charCodeAt(i));
  }
  return new Uint8Array(arr);
A
Annie_wang 已提交
2409 2410
}

A
Annie_wang 已提交
2411 2412
function updateSession(handle:number, huksOptions:huks.HuksOptions, token:Uint8Array, throwObject) : Promise<huks.HuksReturnResult> {
  return new Promise((resolve, reject) => {
A
Annie_wang 已提交
2413
    try {
A
Annie_wang 已提交
2414 2415 2416 2417 2418 2419 2420
      huks.updateSession(handle, huksOptions, token, function (error, data) {
        if (error) {
          reject(error);
        } else {
          resolve(data);
        }
      });
A
Annie_wang 已提交
2421
    } catch (error) {
A
Annie_wang 已提交
2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445
      throwObject.isThrow = true;
      throw(error);
    }
  });
}

async function publicUpdateFunc(handle:number, token:Uint8Array, huksOptions:huks.HuksOptions) {
  console.info(`enter callback doUpdate`);
  let throwObject = {isThrow: false};
  try {
    await updateSession(handle, huksOptions, token, throwObject)
      .then ((data) => {
        console.info(`callback: doUpdate success, data = ${JSON.stringify(data)}`);
      })
      .catch(error => {
        if (throwObject.isThrow) {
          throw(error);
        } else {
          console.error(`callback: doUpdate failed, code: ${error.code}, msg: ${error.message}`);
        }
      });
  } catch (error) {
    console.error(`callback: doUpdate input arg invalid, code: ${error.code}, msg: ${error.message}`);
  }
A
Annie_wang 已提交
2446 2447
}

A
Annie_wang 已提交
2448 2449 2450 2451 2452 2453 2454 2455
function finishSession(handle:number, huksOptions:huks.HuksOptions, token:Uint8Array, throwObject) : Promise<huks.HuksReturnResult> {
  return new Promise((resolve, reject) => {
    try {
      huks.finishSession(handle, huksOptions, token, function (error, data) {
        if (error) {
          reject(error);
        } else {
          resolve(data);
A
Annie_wang 已提交
2456
        }
A
Annie_wang 已提交
2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483
      });
    } catch (error) {
      throwObject.isThrow = true;
      throw(error);
    }
  });
}

async function publicFinishFunc(handle:number, token:Uint8Array, huksOptions:huks.HuksOptions) {
  console.info(`enter callback doFinish`);
  let throwObject = {isThrow: false};
  try {
    await finishSession(handle, huksOptions, token, throwObject)
      .then ((data) => {
        finishOutData = data.outData;
        console.info(`callback: doFinish success, data = ${JSON.stringify(data)}`);
      })
      .catch(error => {
        if (throwObject.isThrow) {
          throw(error);
        } else {
          console.error(`callback: doFinish failed, code: ${error.code}, msg: ${error.message}`);
        }
      });
  } catch (error) {
    console.error(`callback: doFinish input arg invalid, code: ${error.code}, msg: ${error.message}`);
  }
A
Annie_wang 已提交
2484 2485
}

A
Annie_wang 已提交
2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499
async function testSm4Cipher() {
  encryptOptions.inData = StringToUint8Array(cipherInData);
  /* Pass in the authentication token. */
  await publicUpdateFunc(handle, fingerAuthToken, encryptOptions);
  encryptUpdateResult = updateResult;

  encryptOptions.inData = new Uint8Array(new Array());
  /* Pass in the authentication token. */
  await publicFinishFunc(handle, fingerAuthToken, encryptOptions);
  if (finishOutData === cipherInData) {
    console.info('test finish encrypt err ');
  } else {
    console.info('test finish encrypt success');
  }
A
Annie_wang 已提交
2500 2501 2502
}
```

A
Annie_wang 已提交
2503
## Key Attestation
A
Annie_wang 已提交
2504

A
Annie_wang 已提交
2505
The HUKS provides attestation for the public keys of asymmetric key pairs. The HUKS can issue a certificate for the public key of an asymmetric key pair stored in the HUKS using the public key infrastructure (PKI) certificate chain technology. The certificate can prove the validity of the public key. The service can use the root CA certificate provided by the OpenHarmony to verify the key certificate issued by the HUKS level by level to ensure that the public key and private key in the certificate are from a trusted hardware device and stored in the HUKS.
A
Annie_wang 已提交
2506

A
Annie_wang 已提交
2507 2508 2509 2510
**How to Develop**
1. Pass in the key alias and the attribute tag of the key to be attested.
2. Call a HUKS API to generate an X.509 certificate chain, which consists of the root CA certificate, device CA certificate, device certificate, and key certificate in sequence, for the application.
3. Send the certificate chain to a trusted server. The server parses and verifies the validity of the certificate chain and whether a single certificate is revoked.
A
Annie_wang 已提交
2511

A
Annie_wang 已提交
2512
**Available APIs**
A
Annie_wang 已提交
2513

A
Annie_wang 已提交
2514 2515 2516 2517
**Table 7** APIs for key attestation
| API                     | Description                |
| -------------------------------------- | ----------------------------|
|attestKeyItem(keyAlias: string, options: HuksOptions, callback: AsyncCallback\<HuksReturnResult>) : void| Attests a key.|
A
Annie_wang 已提交
2518

A
Annie_wang 已提交
2519
**How to Develop**
A
Annie_wang 已提交
2520

A
Annie_wang 已提交
2521 2522 2523 2524 2525
```ts
/*
 * Attest a key and return the result in a callback.
 */
import huks from '@ohos.security.huks';
A
Annie_wang 已提交
2526

A
Annie_wang 已提交
2527 2528 2529 2530 2531 2532 2533 2534 2535 2536
/*
 * Determine the key alias and encapsulate the key attribute set.
 */
let keyAliasString = "key attest";
let aliasString = keyAliasString;
let aliasUint8 = StringToUint8Array(keyAliasString);
let securityLevel = StringToUint8Array('sec_level');
let challenge = StringToUint8Array('challenge_data');
let versionInfo = StringToUint8Array('version_info');
let attestCertChain;
A
Annie_wang 已提交
2537

A
Annie_wang 已提交
2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573
let genKeyProperties = new Array();
genKeyProperties[0] = {
    tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
    value: huks.HuksKeyAlg.HUKS_ALG_RSA
};
genKeyProperties[1] = {
    tag: huks.HuksTag.HUKS_TAG_KEY_STORAGE_FLAG,
    value: huks.HuksKeyStorageType.HUKS_STORAGE_PERSISTENT
};
genKeyProperties[2] = {
    tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
    value: huks.HuksKeySize.HUKS_RSA_KEY_SIZE_2048
};
genKeyProperties[3] = {
    tag: huks.HuksTag.HUKS_TAG_PURPOSE,
    value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_VERIFY
};
genKeyProperties[4] = {
    tag: huks.HuksTag.HUKS_TAG_DIGEST,
    value: huks.HuksKeyDigest.HUKS_DIGEST_SHA256
};
genKeyProperties[5] = {
    tag: huks.HuksTag.HUKS_TAG_PADDING,
    value: huks.HuksKeyPadding.HUKS_PADDING_PSS
};
genKeyProperties[6] = {
    tag: huks.HuksTag.HUKS_TAG_KEY_GENERATE_TYPE,
    value: huks.HuksKeyGenerateType.HUKS_KEY_GENERATE_TYPE_DEFAULT
};
genKeyProperties[7] = {
    tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE,
    value: huks.HuksCipherMode.HUKS_MODE_ECB
};
let genOptions = {
    properties: genKeyProperties
};
A
Annie_wang 已提交
2574

A
Annie_wang 已提交
2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594
let attestKeyproperties = new Array();
attestKeyproperties[0] = {
    tag: huks.HuksTag.HUKS_TAG_ATTESTATION_ID_SEC_LEVEL_INFO,
    value: securityLevel
};
attestKeyproperties[1] = {
    tag: huks.HuksTag.HUKS_TAG_ATTESTATION_CHALLENGE,
    value: challenge
};
attestKeyproperties[2] = {
    tag: huks.HuksTag.HUKS_TAG_ATTESTATION_ID_VERSION_INFO,
    value: versionInfo
};
attestKeyproperties[3] = {
    tag: huks.HuksTag.HUKS_TAG_ATTESTATION_ID_ALIAS,
    value: aliasUint8
};
let huksOptions = {
    properties: attestKeyproperties
};
A
Annie_wang 已提交
2595 2596 2597 2598

function StringToUint8Array(str) {
    let arr = [];
    for (let i = 0, j = str.length; i < j; ++i) {
A
Annie_wang 已提交
2599 2600
        arr.push(str.charCodeAt(i));
    }
A
Annie_wang 已提交
2601 2602 2603
    return new Uint8Array(arr);
}

A
Annie_wang 已提交
2604
function generateKeyItem(keyAlias:string, huksOptions:huks.HuksOptions, throwObject) {
A
Annie_wang 已提交
2605 2606 2607 2608 2609 2610 2611 2612 2613 2614
    return new Promise((resolve, reject) => {
        try {
            huks.generateKeyItem(keyAlias, huksOptions, function (error, data) {
                if (error) {
                    reject(error);
                } else {
                    resolve(data);
                }
            });
        } catch (error) {
A
Annie_wang 已提交
2615
            throwObject.isThrow = true;
A
Annie_wang 已提交
2616 2617 2618 2619 2620
            throw(error);
        }
    });
}

A
Annie_wang 已提交
2621 2622 2623
async function publicGenKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
    console.info(`enter callback generateKeyItem`);
    let throwObject = {isThrow: false};
A
Annie_wang 已提交
2624
    try {
A
Annie_wang 已提交
2625 2626 2627
        await generateKeyItem(keyAlias, huksOptions, throwObject)
            .then((data) => {
                console.info(`callback: generateKeyItem success, data = ${JSON.stringify(data)}`);
A
Annie_wang 已提交
2628 2629
            })
            .catch(error => {
A
Annie_wang 已提交
2630 2631 2632 2633 2634
                if (throwObject.isThrow) {
                    throw(error);
                } else {
                    console.error(`callback: generateKeyItem failed, code: ${error.code}, msg: ${error.message}`);
                }
A
Annie_wang 已提交
2635 2636
            });
    } catch (error) {
A
Annie_wang 已提交
2637
        console.error(`callback: generateKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
A
Annie_wang 已提交
2638 2639 2640
    }
}

A
Annie_wang 已提交
2641
function attestKeyItem(keyAlias:string, huksOptions:huks.HuksOptions, throwObject) : Promise<huks.HuksReturnResult>{
A
Annie_wang 已提交
2642 2643 2644 2645 2646 2647 2648 2649 2650 2651
    return new Promise((resolve, reject) => {
        try {
            huks.attestKeyItem(keyAlias, huksOptions, function (error, data) {
                if (error) {
                    reject(error);
                } else {
                    resolve(data);
                }
            });
        } catch (error) {
A
Annie_wang 已提交
2652
            throwObject.isThrow = true;
A
Annie_wang 已提交
2653 2654 2655 2656 2657
            throw(error);
        }
    });
}

A
Annie_wang 已提交
2658 2659 2660
async function publicAttestKey(keyAlias:string, huksOptions:huks.HuksOptions) {
    console.info(`enter callback attestKeyItem`);
    let throwObject = {isThrow: false};
A
Annie_wang 已提交
2661
    try {
A
Annie_wang 已提交
2662
        await attestKeyItem(keyAlias, huksOptions, throwObject)
A
Annie_wang 已提交
2663
            .then ((data) => {
A
Annie_wang 已提交
2664 2665 2666 2667
                console.info(`callback: attestKeyItem success, data = ${JSON.stringify(data)}`);
                if (data !== null && data.certChains !== null) {
                    attestCertChain = data.certChains;
                }
A
Annie_wang 已提交
2668 2669
            })
            .catch(error => {
A
Annie_wang 已提交
2670 2671 2672 2673 2674
                if (throwObject.isThrow) {
                    throw(error);
                } else {
                    console.error(`callback: attestKeyItem failed, code: ${error.code}, msg: ${error.message}`);
                }
A
Annie_wang 已提交
2675 2676
            });
    } catch (error) {
A
Annie_wang 已提交
2677
        console.error(`callback: attestKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
A
Annie_wang 已提交
2678
    }
A
Annie_wang 已提交
2679 2680
}

A
Annie_wang 已提交
2681 2682 2683 2684 2685
async function AttestKeyTest() {
    await publicGenKeyFunc(aliasString, genOptions);

    await publicAttestKey(aliasString, huksOptions);
    console.info('attest certChain data: ' + attestCertChain)
A
Annie_wang 已提交
2686
}
A
Annie_wang 已提交
2687
```
A
Annie_wang 已提交
2688

A
Annie_wang 已提交
2689
## FAQs
A
Annie_wang 已提交
2690

A
Annie_wang 已提交
2691
### Cannot find name 'huks'.
A
Annie_wang 已提交
2692

A
Annie_wang 已提交
2693
**security.huks.d.ts** is not imported. To solve the problem, add **import huks from '@ohos.security.huks'**.
A
Annie_wang 已提交
2694

A
Annie_wang 已提交
2695 2696 2697
### Property 'finishSession' does not exist on type 'typeof huks'. Did you mean 'finish'?

**finishSession()** is supported from API version 9. Update the SDK version or use the latest **security.huks.d.ts** file.