1# 密钥派生(ArkTS) 2 3 4以HKDF256密钥为例,完成密钥派生。具体的场景介绍及支持的算法规格,请参考[密钥生成支持的算法](huks-key-generation-overview.md#支持的算法)。 5 6 7## 开发步骤 8 9**生成密钥** 10 111. 指定密钥别名。 12 132. 初始化密钥属性集,可指定参数TAG(可选),HUKS_TAG_DERIVED_AGREED_KEY_STORAGE_FLAG: 14 - HUKS_STORAGE_ONLY_USED_IN_HUKS:表示由该密钥派生出的密钥存储于HUKS中,由HUKS进行托管。 15 - HUKS_STORAGE_KEY_EXPORT_ALLOWED(默认):表示由该密钥派生出的密钥直接导出给业务方,HUKS不对其进行托管服务。 16 173. 调用[generateKeyItem](../../reference/apis-universal-keystore-kit/js-apis-huks.md#huksgeneratekeyitem9)生成密钥,具体请参考[密钥生成](huks-key-generation-overview.md)。 18 19除此之外,开发者也可以参考[密钥导入](huks-key-import-overview.md),导入已有的密钥。 20 21**密钥派生** 22 231. 获取密钥别名、指定对应的属性参数HuksOptions。 24 252. 调用[initSession](../../reference/apis-universal-keystore-kit/js-apis-huks.md#huksinitsession9)初始化密钥会话,并获取会话的句柄handle。 26 273. 调用[updateSession](../../reference/apis-universal-keystore-kit/js-apis-huks.md#huksupdatesession9)更新密钥会话。 28 294. 调用[finishSession](../../reference/apis-universal-keystore-kit/js-apis-huks.md#huksfinishsession9)结束密钥会话,完成派生。 30 31**删除密钥** 32 33当密钥废弃不用时,需要调用[deleteKeyItem](../../reference/apis-universal-keystore-kit/js-apis-huks.md#huksdeletekeyitem9)删除密钥,具体请参考[密钥删除](huks-delete-key-arkts.md)。 34 35```ts 36/* 37 * 以下以HKDF256密钥的Promise操作使用为例 38 */ 39import huks from '@ohos.security.huks'; 40import { BusinessError } from '@ohos.base'; 41/* 42 * 确定密钥别名和封装密钥属性参数集 43 */ 44let srcKeyAlias = "hkdf_Key"; 45let deriveHkdfInData = "deriveHkdfTestIndata"; 46let handle:number; 47let finishOutData:Uint8Array; 48let HuksKeyDeriveKeySize = 32; 49/* 集成生成密钥参数集 */ 50let properties:Array<huks.HuksParam> = new Array(); 51properties[0] = { 52 tag: huks.HuksTag.HUKS_TAG_ALGORITHM, 53 value: huks.HuksKeyAlg.HUKS_ALG_AES, 54} 55properties[1] = { 56 tag: huks.HuksTag.HUKS_TAG_PURPOSE, 57 value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DERIVE, 58} 59properties[2] = { 60 tag: huks.HuksTag.HUKS_TAG_DIGEST, 61 value: huks.HuksKeyDigest.HUKS_DIGEST_SHA256, 62} 63properties[3] = { 64 tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, 65 value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_128, 66} 67properties[4] = { 68 tag: huks.HuksTag.HUKS_TAG_DERIVED_AGREED_KEY_STORAGE_FLAG, 69 value: huks.HuksKeyStorageType.HUKS_STORAGE_ONLY_USED_IN_HUKS, 70} 71let huksOptions:huks.HuksOptions = { 72 properties: properties, 73 inData: new Uint8Array(new Array()) 74} 75/* 集成init时密钥参数集 */ 76let initProperties:Array<huks.HuksParam> = new Array(); 77initProperties[0] = { 78 tag: huks.HuksTag.HUKS_TAG_ALGORITHM, 79 value: huks.HuksKeyAlg.HUKS_ALG_HKDF, 80} 81initProperties[1] = { 82 tag: huks.HuksTag.HUKS_TAG_PURPOSE, 83 value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DERIVE, 84} 85initProperties[2] = { 86 tag: huks.HuksTag.HUKS_TAG_DIGEST, 87 value: huks.HuksKeyDigest.HUKS_DIGEST_SHA256, 88} 89initProperties[3] = { 90 tag: huks.HuksTag.HUKS_TAG_DERIVE_KEY_SIZE, 91 value: HuksKeyDeriveKeySize, 92} 93let initOptions:huks.HuksOptions = { 94 properties: initProperties, 95 inData: new Uint8Array(new Array()) 96} 97/* 集成finish时密钥参数集 */ 98let finishProperties:Array<huks.HuksParam> = new Array(); 99finishProperties[0] = { 100 tag: huks.HuksTag.HUKS_TAG_DERIVED_AGREED_KEY_STORAGE_FLAG, 101 value: huks.HuksKeyStorageType.HUKS_STORAGE_ONLY_USED_IN_HUKS, 102} 103finishProperties[1] = { 104 tag: huks.HuksTag.HUKS_TAG_IS_KEY_ALIAS, 105 value: true, 106} 107finishProperties[2] = { 108 tag: huks.HuksTag.HUKS_TAG_ALGORITHM, 109 value: huks.HuksKeyAlg.HUKS_ALG_AES, 110} 111finishProperties[3] = { 112 tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, 113 value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_256, 114} 115finishProperties[4] = { 116 tag: huks.HuksTag.HUKS_TAG_PURPOSE, 117 value: 118 huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT | 119 huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT, 120} 121finishProperties[5] = { 122 tag: huks.HuksTag.HUKS_TAG_DIGEST, 123 value: huks.HuksKeyDigest.HUKS_DIGEST_NONE, 124} 125finishProperties[6] = { 126 tag: huks.HuksTag.HUKS_TAG_KEY_ALIAS, 127 value: StringToUint8Array(srcKeyAlias), 128} 129finishProperties[7] = { 130 tag: huks.HuksTag.HUKS_TAG_PADDING, 131 value: huks.HuksKeyPadding.HUKS_PADDING_NONE, 132} 133finishProperties[8] = { 134 tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE, 135 value: huks.HuksCipherMode.HUKS_MODE_ECB, 136} 137let finishOptions:huks.HuksOptions = { 138 properties: finishProperties, 139 inData: new Uint8Array(new Array()) 140} 141function StringToUint8Array(str:String) { 142 let arr:number[]=new Array(); 143 for (let i = 0, j = str.length; i < j; ++i) { 144 arr.push(str.charCodeAt(i)); 145 } 146 return new Uint8Array(arr); 147} 148class throwObject{ 149 isThrow=false; 150} 151function generateKeyItem(keyAlias:string, huksOptions:huks.HuksOptions, throwObject:throwObject) { 152 return new Promise<void>((resolve, reject) => { 153 try { 154 huks.generateKeyItem(keyAlias, huksOptions, (error, data)=> { 155 if (error) { 156 reject(error); 157 } else { 158 resolve(data); 159 } 160 }); 161 } catch (error) { 162 throwObject.isThrow = true; 163 throw(error as Error); 164 } 165 }); 166} 167async function publicGenKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) { 168 console.info(`enter promise generateKeyItem`); 169 let throwObject:throwObject = {isThrow: false}; 170 try { 171 await generateKeyItem(keyAlias, huksOptions, throwObject) 172 .then((data) => { 173 console.info(`promise: generateKeyItem success, data = ${JSON.stringify(data)}`); 174 }) 175 .catch((error:BusinessError) => { 176 if (throwObject.isThrow) { 177 throw(error as Error); 178 } else { 179 console.error(`promise: generateKeyItem failed` + error); 180 } 181 }); 182 } catch (error) { 183 console.error(`promise: generateKeyItem input arg invalid` + error); 184 } 185} 186function initSession(keyAlias:string, huksOptions:huks.HuksOptions, throwObject:throwObject) { 187 return new Promise<huks.HuksSessionHandle>((resolve, reject) => { 188 try { 189 huks.initSession(keyAlias, huksOptions, (error, data)=> { 190 if (error) { 191 reject(error); 192 } else { 193 resolve(data); 194 } 195 }); 196 } catch (error) { 197 throwObject.isThrow = true; 198 throw(error as Error); 199 } 200 }); 201} 202async function publicInitFunc(keyAlias:string, huksOptions:huks.HuksOptions) { 203 console.info(`enter promise doInit`); 204 let throwObject:throwObject = {isThrow: false}; 205 try { 206 await initSession(keyAlias, huksOptions, throwObject) 207 .then ((data) => { 208 console.info(`promise: doInit success, data = ${JSON.stringify(data)}`); 209 handle = data.handle; 210 }) 211 .catch((error:BusinessError) => { 212 if (throwObject.isThrow) { 213 throw(error as Error); 214 } else { 215 console.error(`promise: doInit failed` + error); 216 } 217 }); 218 } catch (error) { 219 console.error(`promise: doInit input arg invalid` + error); 220 } 221} 222function updateSession(handle:number, huksOptions:huks.HuksOptions, throwObject:throwObject) { 223 return new Promise<huks.HuksOptions>((resolve, reject) => { 224 try { 225 huks.updateSession(handle, huksOptions, (error, data)=> { 226 if (error) { 227 reject(error); 228 } else { 229 resolve(data); 230 } 231 }); 232 } catch (error) { 233 throwObject.isThrow = true; 234 throw(error as Error); 235 } 236 }); 237} 238async function publicUpdateFunc(handle:number, huksOptions:huks.HuksOptions) { 239 console.info(`enter promise doUpdate`); 240 let throwObject:throwObject = {isThrow: false}; 241 try { 242 await updateSession(handle, huksOptions, throwObject) 243 .then ((data) => { 244 console.info(`promise: doUpdate success, data = ${JSON.stringify(data)}`); 245 }) 246 .catch((error:BusinessError) => { 247 if (throwObject.isThrow) { 248 throw(error as Error); 249 } else { 250 console.error(`promise: doUpdate failed` + error); 251 } 252 }); 253 } catch (error) { 254 console.error(`promise: doUpdate input arg invalid` + error); 255 } 256} 257function finishSession(handle:number, huksOptions:huks.HuksOptions, throwObject:throwObject) { 258 return new Promise<huks.HuksReturnResult>((resolve, reject) => { 259 try { 260 huks.finishSession(handle, huksOptions, (error, data)=> { 261 if (error) { 262 reject(error); 263 } else { 264 resolve(data); 265 } 266 }); 267 } catch (error) { 268 throwObject.isThrow = true; 269 throw(error as Error); 270 } 271 }); 272} 273async function publicFinishFunc(handle:number, huksOptions:huks.HuksOptions) { 274 console.info(`enter promise doFinish`); 275 let throwObject:throwObject = {isThrow: false}; 276 try { 277 await finishSession(handle, huksOptions, throwObject) 278 .then ((data) => { 279 finishOutData = data.outData as Uint8Array; 280 console.info(`promise: doFinish success, data = ${JSON.stringify(data)}`); 281 }) 282 .catch((error:BusinessError) => { 283 if (throwObject.isThrow) { 284 throw(error as Error); 285 } else { 286 console.error(`promise: doFinish failed` + error); 287 } 288 }); 289 } catch (error) { 290 console.error(`promise: doFinish input arg invalid` + error); 291 } 292} 293function deleteKeyItem(keyAlias:string, huksOptions:huks.HuksOptions, throwObject:throwObject) { 294 return new Promise<void>((resolve, reject) => { 295 try { 296 huks.deleteKeyItem(keyAlias, huksOptions, (error, data)=> { 297 if (error) { 298 reject(error); 299 } else { 300 resolve(data); 301 } 302 }); 303 } catch (error) { 304 throwObject.isThrow = true; 305 throw(error as Error); 306 } 307 }); 308} 309async function publicDeleteKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) { 310 console.info(`enter promise deleteKeyItem`); 311 let throwObject:throwObject = {isThrow: false}; 312 try { 313 await deleteKeyItem(keyAlias, huksOptions, throwObject) 314 .then ((data) => { 315 console.info(`promise: deleteKeyItem key success, data = ${JSON.stringify(data)}`); 316 }) 317 .catch((error:BusinessError) => { 318 if (throwObject.isThrow) { 319 throw(error as Error); 320 } else { 321 console.error(`promise: deleteKeyItem failed` + error); 322 } 323 }); 324 } catch (error) { 325 console.error(`promise: deletKeeyItem input arg invalid` + error); 326 } 327} 328async function testDerive() { 329 /* 生成密钥 */ 330 await publicGenKeyFunc(srcKeyAlias, huksOptions); 331 /* 进行派生操作 */ 332 await publicInitFunc(srcKeyAlias, initOptions); 333 initOptions.inData = StringToUint8Array(deriveHkdfInData); 334 await publicUpdateFunc(handle, initOptions); 335 await publicFinishFunc(handle, finishOptions); 336 await publicDeleteKeyFunc(srcKeyAlias, huksOptions); 337} 338``` 339