1e41f4b71Sopenharmony_ci# Anonymous Key Attestation (ArkTS) 2e41f4b71Sopenharmony_ci 3e41f4b71Sopenharmony_ciEnsure network connection during the operation. 4e41f4b71Sopenharmony_ci 5e41f4b71Sopenharmony_ci## How to Develop 6e41f4b71Sopenharmony_ci 7e41f4b71Sopenharmony_ci1. Set the key alias (**keyAlias**), which cannot exceed 128 bytes. 8e41f4b71Sopenharmony_ci 9e41f4b71Sopenharmony_ci2. Initializes a parameter set. 10e41f4b71Sopenharmony_ci 11e41f4b71Sopenharmony_ci The **properties** field in [HuksOptions](../../reference/apis-universal-keystore-kit/js-apis-huks.md#huksoptions) must contain [HUKS_TAG_ATTESTATION_CHALLENGE](../../reference/apis-universal-keystore-kit/js-apis-huks.md#hukstag). Optional parameters include [HUKS_TAG_ATTESTATION_ID_VERSION_INFO](../../reference/apis-universal-keystore-kit/js-apis-huks.md#hukstag) and [HUKS_TAG_ATTESTATION_ID_ALIAS](../../reference/apis-universal-keystore-kit/js-apis-huks.md#hukstag). 12e41f4b71Sopenharmony_ci 13e41f4b71Sopenharmony_ci3. Generate an asymmetric key. For details, see [Key Generation](huks-key-generation-overview.md). 14e41f4b71Sopenharmony_ci 15e41f4b71Sopenharmony_ci4. Use [huks.anonAttestKeyItem](../../reference/apis-universal-keystore-kit/js-apis-huks.md#huksanonattestkeyitem11) with the key alias and parameter set to perform key attestation. 16e41f4b71Sopenharmony_ci 17e41f4b71Sopenharmony_ci```ts 18e41f4b71Sopenharmony_ci/* 19e41f4b71Sopenharmony_ci * Perform anonymous key attestation. This example uses promise-based APIs. 20e41f4b71Sopenharmony_ci */ 21e41f4b71Sopenharmony_ciimport { huks } from '@kit.UniversalKeystoreKit'; 22e41f4b71Sopenharmony_ci 23e41f4b71Sopenharmony_ci/* 1. Set the key alias. */ 24e41f4b71Sopenharmony_cilet keyAliasString = "key anon attest"; 25e41f4b71Sopenharmony_cilet aliasString = keyAliasString; 26e41f4b71Sopenharmony_cilet aliasUint8 = StringToUint8Array(keyAliasString); 27e41f4b71Sopenharmony_cilet securityLevel = StringToUint8Array('sec_level'); 28e41f4b71Sopenharmony_cilet challenge = StringToUint8Array('challenge_data'); 29e41f4b71Sopenharmony_cilet versionInfo = StringToUint8Array('version_info'); 30e41f4b71Sopenharmony_cilet anonAttestCertChain: Array<string>; 31e41f4b71Sopenharmony_ci 32e41f4b71Sopenharmony_ciclass throwObject { 33e41f4b71Sopenharmony_ci isThrow: boolean = false; 34e41f4b71Sopenharmony_ci} 35e41f4b71Sopenharmony_ci 36e41f4b71Sopenharmony_ci/* Encapsulate the key parameter set. */ 37e41f4b71Sopenharmony_cilet genKeyProperties: Array<huks.HuksParam> = [ 38e41f4b71Sopenharmony_ci { 39e41f4b71Sopenharmony_ci tag: huks.HuksTag.HUKS_TAG_ALGORITHM, 40e41f4b71Sopenharmony_ci value: huks.HuksKeyAlg.HUKS_ALG_RSA 41e41f4b71Sopenharmony_ci }, 42e41f4b71Sopenharmony_ci { 43e41f4b71Sopenharmony_ci tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, 44e41f4b71Sopenharmony_ci value: huks.HuksKeySize.HUKS_RSA_KEY_SIZE_2048 45e41f4b71Sopenharmony_ci }, 46e41f4b71Sopenharmony_ci { 47e41f4b71Sopenharmony_ci tag: huks.HuksTag.HUKS_TAG_PURPOSE, 48e41f4b71Sopenharmony_ci value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_VERIFY 49e41f4b71Sopenharmony_ci }, 50e41f4b71Sopenharmony_ci { 51e41f4b71Sopenharmony_ci tag: huks.HuksTag.HUKS_TAG_DIGEST, 52e41f4b71Sopenharmony_ci value: huks.HuksKeyDigest.HUKS_DIGEST_SHA256 53e41f4b71Sopenharmony_ci }, 54e41f4b71Sopenharmony_ci { 55e41f4b71Sopenharmony_ci tag: huks.HuksTag.HUKS_TAG_PADDING, 56e41f4b71Sopenharmony_ci value: huks.HuksKeyPadding.HUKS_PADDING_PSS 57e41f4b71Sopenharmony_ci }, 58e41f4b71Sopenharmony_ci { 59e41f4b71Sopenharmony_ci tag: huks.HuksTag.HUKS_TAG_KEY_GENERATE_TYPE, 60e41f4b71Sopenharmony_ci value: huks.HuksKeyGenerateType.HUKS_KEY_GENERATE_TYPE_DEFAULT 61e41f4b71Sopenharmony_ci }, 62e41f4b71Sopenharmony_ci { 63e41f4b71Sopenharmony_ci tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE, 64e41f4b71Sopenharmony_ci value: huks.HuksCipherMode.HUKS_MODE_ECB 65e41f4b71Sopenharmony_ci } 66e41f4b71Sopenharmony_ci] 67e41f4b71Sopenharmony_cilet genOptions: huks.HuksOptions = { 68e41f4b71Sopenharmony_ci properties: genKeyProperties 69e41f4b71Sopenharmony_ci}; 70e41f4b71Sopenharmony_ci 71e41f4b71Sopenharmony_ci/* 2. Encapsulate the parameter set for key attestation. */ 72e41f4b71Sopenharmony_cilet anonAttestKeyProperties: Array<huks.HuksParam> = [ 73e41f4b71Sopenharmony_ci { 74e41f4b71Sopenharmony_ci tag: huks.HuksTag.HUKS_TAG_ATTESTATION_ID_SEC_LEVEL_INFO, 75e41f4b71Sopenharmony_ci value: securityLevel 76e41f4b71Sopenharmony_ci }, 77e41f4b71Sopenharmony_ci { 78e41f4b71Sopenharmony_ci tag: huks.HuksTag.HUKS_TAG_ATTESTATION_CHALLENGE, 79e41f4b71Sopenharmony_ci value: challenge 80e41f4b71Sopenharmony_ci }, 81e41f4b71Sopenharmony_ci { 82e41f4b71Sopenharmony_ci tag: huks.HuksTag.HUKS_TAG_ATTESTATION_ID_VERSION_INFO, 83e41f4b71Sopenharmony_ci value: versionInfo 84e41f4b71Sopenharmony_ci }, 85e41f4b71Sopenharmony_ci { 86e41f4b71Sopenharmony_ci tag: huks.HuksTag.HUKS_TAG_ATTESTATION_ID_ALIAS, 87e41f4b71Sopenharmony_ci value: aliasUint8 88e41f4b71Sopenharmony_ci } 89e41f4b71Sopenharmony_ci] 90e41f4b71Sopenharmony_cilet huksOptions: huks.HuksOptions = { 91e41f4b71Sopenharmony_ci properties: anonAttestKeyProperties 92e41f4b71Sopenharmony_ci}; 93e41f4b71Sopenharmony_ci 94e41f4b71Sopenharmony_cifunction StringToUint8Array(str: string) { 95e41f4b71Sopenharmony_ci let arr: number[] = []; 96e41f4b71Sopenharmony_ci for (let i = 0, j = str.length; i < j; ++i) { 97e41f4b71Sopenharmony_ci arr.push(str.charCodeAt(i)); 98e41f4b71Sopenharmony_ci } 99e41f4b71Sopenharmony_ci return new Uint8Array(arr); 100e41f4b71Sopenharmony_ci} 101e41f4b71Sopenharmony_ci 102e41f4b71Sopenharmony_cifunction generateKeyItem(keyAlias: string, huksOptions: huks.HuksOptions, throwObject: throwObject) { 103e41f4b71Sopenharmony_ci return new Promise<void>((resolve, reject) => { 104e41f4b71Sopenharmony_ci try { 105e41f4b71Sopenharmony_ci huks.generateKeyItem(keyAlias, huksOptions, (error, data) => { 106e41f4b71Sopenharmony_ci if (error) { 107e41f4b71Sopenharmony_ci reject(error); 108e41f4b71Sopenharmony_ci } else { 109e41f4b71Sopenharmony_ci resolve(data); 110e41f4b71Sopenharmony_ci } 111e41f4b71Sopenharmony_ci }); 112e41f4b71Sopenharmony_ci } catch (error) { 113e41f4b71Sopenharmony_ci throwObject.isThrow = true; 114e41f4b71Sopenharmony_ci throw (error as Error); 115e41f4b71Sopenharmony_ci } 116e41f4b71Sopenharmony_ci }); 117e41f4b71Sopenharmony_ci} 118e41f4b71Sopenharmony_ci 119e41f4b71Sopenharmony_ci/* 3. Generate a key. */ 120e41f4b71Sopenharmony_ciasync function publicGenKeyFunc(keyAlias: string, huksOptions: huks.HuksOptions) { 121e41f4b71Sopenharmony_ci console.info(`enter promise generateKeyItem`); 122e41f4b71Sopenharmony_ci let throwObject: throwObject = { isThrow: false }; 123e41f4b71Sopenharmony_ci try { 124e41f4b71Sopenharmony_ci await generateKeyItem(keyAlias, huksOptions, throwObject) 125e41f4b71Sopenharmony_ci .then((data) => { 126e41f4b71Sopenharmony_ci console.info(`promise: generateKeyItem success, data = ${JSON.stringify(data)}`); 127e41f4b71Sopenharmony_ci }) 128e41f4b71Sopenharmony_ci .catch((error: Error) => { 129e41f4b71Sopenharmony_ci if (throwObject.isThrow) { 130e41f4b71Sopenharmony_ci throw (error as Error); 131e41f4b71Sopenharmony_ci } else { 132e41f4b71Sopenharmony_ci console.error(`promise: generateKeyItem failed, ${JSON.stringify(error)}`); 133e41f4b71Sopenharmony_ci } 134e41f4b71Sopenharmony_ci }); 135e41f4b71Sopenharmony_ci } catch (error) { 136e41f4b71Sopenharmony_ci console.error(`promise: generateKeyItem input arg invalid, ${JSON.stringify(error)}`); 137e41f4b71Sopenharmony_ci } 138e41f4b71Sopenharmony_ci} 139e41f4b71Sopenharmony_ci 140e41f4b71Sopenharmony_ci/* 4. Attest the key. */ 141e41f4b71Sopenharmony_cifunction anonAttestKeyItem(keyAlias: string, huksOptions: huks.HuksOptions, throwObject: throwObject) { 142e41f4b71Sopenharmony_ci return new Promise<huks.HuksReturnResult>((resolve, reject) => { 143e41f4b71Sopenharmony_ci try { 144e41f4b71Sopenharmony_ci huks.anonAttestKeyItem(keyAlias, huksOptions, (error, data) => { 145e41f4b71Sopenharmony_ci if (error) { 146e41f4b71Sopenharmony_ci reject(error); 147e41f4b71Sopenharmony_ci } else { 148e41f4b71Sopenharmony_ci resolve(data); 149e41f4b71Sopenharmony_ci } 150e41f4b71Sopenharmony_ci }); 151e41f4b71Sopenharmony_ci } catch (error) { 152e41f4b71Sopenharmony_ci throwObject.isThrow = true; 153e41f4b71Sopenharmony_ci throw (error as Error); 154e41f4b71Sopenharmony_ci } 155e41f4b71Sopenharmony_ci }); 156e41f4b71Sopenharmony_ci} 157e41f4b71Sopenharmony_ci 158e41f4b71Sopenharmony_ciasync function publicAnonAttestKey(keyAlias: string, huksOptions: huks.HuksOptions) { 159e41f4b71Sopenharmony_ci console.info(`enter promise anonAttestKeyItem`); 160e41f4b71Sopenharmony_ci let throwObject: throwObject = { isThrow: false }; 161e41f4b71Sopenharmony_ci try { 162e41f4b71Sopenharmony_ci await anonAttestKeyItem(keyAlias, huksOptions, throwObject) 163e41f4b71Sopenharmony_ci .then((data) => { 164e41f4b71Sopenharmony_ci console.info(`promise: anonAttestKeyItem success, data = ${JSON.stringify(data)}`); 165e41f4b71Sopenharmony_ci if (data !== null && data.certChains !== null) { 166e41f4b71Sopenharmony_ci anonAttestCertChain = data.certChains as string[]; 167e41f4b71Sopenharmony_ci } 168e41f4b71Sopenharmony_ci }) 169e41f4b71Sopenharmony_ci .catch((error: Error) => { 170e41f4b71Sopenharmony_ci if (throwObject.isThrow) { 171e41f4b71Sopenharmony_ci throw (error as Error); 172e41f4b71Sopenharmony_ci } else { 173e41f4b71Sopenharmony_ci console.error(`promise: anonAttestKeyItem failed, ${JSON.stringify(error)}`); 174e41f4b71Sopenharmony_ci } 175e41f4b71Sopenharmony_ci }); 176e41f4b71Sopenharmony_ci } catch (error) { 177e41f4b71Sopenharmony_ci console.error(`promise: anonAttestKeyItem input arg invalid, ${JSON.stringify(error)}`); 178e41f4b71Sopenharmony_ci } 179e41f4b71Sopenharmony_ci} 180e41f4b71Sopenharmony_ci 181e41f4b71Sopenharmony_ciasync function AnonAttestKeyTest() { 182e41f4b71Sopenharmony_ci await publicGenKeyFunc(aliasString, genOptions); 183e41f4b71Sopenharmony_ci await publicAnonAttestKey(aliasString, huksOptions); 184e41f4b71Sopenharmony_ci console.info('anon attest certChain data: ' + anonAttestCertChain) 185e41f4b71Sopenharmony_ci} 186e41f4b71Sopenharmony_ci``` 187