1# 密钥协商(C/C++) 2 3 4以协商密钥类型为ECDH,并密钥仅在HUKS内使用为例,完成密钥协商。具体的场景介绍及支持的算法规格,请参考[密钥生成支持的算法](huks-key-generation-overview.md#支持的算法)。 5 6 7## 开发步骤 8 9**生成密钥** 10 11设备A、设备B各自生成一个非对称密钥,具体请参考[密钥生成](huks-key-generation-overview.md)或[密钥导入](huks-key-import-overview.md)。 12 13密钥生成时,可指定参数TAG(可选),OH_HUKS_TAG_DERIVED_AGREED_KEY_STORAGE_FLAG: 14 15- OH_HUKS_STORAGE_ONLY_USED_IN_HUKS:表示由该密钥协商出的密钥存储于HUKS中,由HUKS进行托管。 16 17- OH_HUKS_STORAGE_KEY_EXPORT_ALLOWED(默认):表示由该密钥协商出的密钥直接导出给业务方,HUKS不对其进行托管服务。 18 19**导出密钥** 20 21设备A、B导出非对称密钥对的公钥材料,具体请参考[密钥导出](huks-export-key-arkts.md)。 22 23**密钥协商** 24 25设备A、B分别基于本端私钥和对端设备的公钥,协商出共享密钥。 26 27**删除密钥** 28 29当密钥废弃不用时,设备A、B均需要删除密钥,具体请参考[密钥删除](huks-delete-key-ndk.md)。 30 31```c++ 32#include "huks/native_huks_api.h" 33#include "huks/native_huks_param.h" 34#include <string.h> 35/* 初始化参数 */ 36OH_Huks_Result InitParamSet( 37 struct OH_Huks_ParamSet **paramSet, 38 const struct OH_Huks_Param *params, 39 uint32_t paramCount) 40{ 41 OH_Huks_Result ret = OH_Huks_InitParamSet(paramSet); 42 if (ret.errorCode != OH_HUKS_SUCCESS) { 43 return ret; 44 } 45 ret = OH_Huks_AddParams(*paramSet, params, paramCount); 46 if (ret.errorCode != OH_HUKS_SUCCESS) { 47 OH_Huks_FreeParamSet(paramSet); 48 return ret; 49 } 50 ret = OH_Huks_BuildParamSet(paramSet); 51 if (ret.errorCode != OH_HUKS_SUCCESS) { 52 OH_Huks_FreeParamSet(paramSet); 53 return ret; 54 } 55 return ret; 56} 57static const uint32_t IV_SIZE = 16; 58static uint8_t IV[IV_SIZE] = { 0 }; // this is a test value, for real use the iv should be different every time 59static struct OH_Huks_Blob g_keyAliasFinal1001 = { 60 (uint32_t)strlen("HksECDHAgreeKeyAliasTest001_1_final"), 61 (uint8_t *)"HksECDHAgreeKeyAliasTest001_1_final" 62}; 63/* 集成密钥参数集 */ 64static struct OH_Huks_Param g_genAgreeParams[] = { 65 { 66 .tag = OH_HUKS_TAG_ALGORITHM, 67 .uint32Param = OH_HUKS_ALG_ECC 68 }, { 69 .tag = OH_HUKS_TAG_PURPOSE, 70 .uint32Param = OH_HUKS_KEY_PURPOSE_AGREE 71 }, { 72 .tag = OH_HUKS_TAG_KEY_SIZE, 73 .uint32Param = OH_HUKS_ECC_KEY_SIZE_256 74 }, { 75 .tag = OH_HUKS_TAG_DIGEST, 76 .uint32Param = OH_HUKS_DIGEST_NONE 77 } 78}; 79static struct OH_Huks_Param g_agreeParamsInit01[] = { 80 { 81 .tag = OH_HUKS_TAG_ALGORITHM, 82 .uint32Param = OH_HUKS_ALG_ECDH 83 }, { 84 .tag = OH_HUKS_TAG_PURPOSE, 85 .uint32Param = OH_HUKS_KEY_PURPOSE_AGREE 86 }, { 87 .tag = OH_HUKS_TAG_KEY_SIZE, 88 .uint32Param = OH_HUKS_ECC_KEY_SIZE_256 89 } 90}; 91static struct OH_Huks_Param g_agreeParamsFinish01[] = { 92 { 93 .tag = OH_HUKS_TAG_DERIVED_AGREED_KEY_STORAGE_FLAG, 94 .uint32Param = OH_HUKS_STORAGE_ONLY_USED_IN_HUKS 95 }, { 96 .tag = OH_HUKS_TAG_ALGORITHM, 97 .uint32Param = OH_HUKS_ALG_AES 98 }, { 99 .tag = OH_HUKS_TAG_KEY_SIZE, 100 .uint32Param = OH_HUKS_AES_KEY_SIZE_256 101 }, { 102 .tag = OH_HUKS_TAG_PURPOSE, 103 .uint32Param = OH_HUKS_KEY_PURPOSE_AGREE 104 }, { 105 .tag = OH_HUKS_TAG_KEY_ALIAS, 106 .blob = g_keyAliasFinal1001 107 }, { 108 .tag = OH_HUKS_TAG_PADDING, 109 .uint32Param = OH_HUKS_PADDING_NONE 110 }, { 111 .tag = OH_HUKS_TAG_BLOCK_MODE, 112 .uint32Param = OH_HUKS_MODE_CBC 113 } 114}; 115static struct OH_Huks_Blob g_keyAliasFinal2001 = { 116 (uint32_t)strlen("HksECDHAgreeKeyAliasTest001_2_final"), 117 (uint8_t *)"HksECDHAgreeKeyAliasTest001_2_final" 118}; 119static struct OH_Huks_Param g_agreeParamsInit02[] = { 120 { 121 .tag = OH_HUKS_TAG_ALGORITHM, 122 .uint32Param = OH_HUKS_ALG_ECDH 123 }, { 124 .tag = OH_HUKS_TAG_PURPOSE, 125 .uint32Param = OH_HUKS_KEY_PURPOSE_AGREE 126 }, { 127 .tag = OH_HUKS_TAG_KEY_SIZE, 128 .uint32Param = OH_HUKS_ECC_KEY_SIZE_256 129 } 130}; 131static struct OH_Huks_Param g_agreeParamsFinish02[] = { 132 { 133 .tag = OH_HUKS_TAG_DERIVED_AGREED_KEY_STORAGE_FLAG, 134 .uint32Param = OH_HUKS_STORAGE_ONLY_USED_IN_HUKS 135 }, { 136 .tag = OH_HUKS_TAG_ALGORITHM, 137 .uint32Param = OH_HUKS_ALG_AES 138 }, { 139 .tag = OH_HUKS_TAG_KEY_SIZE, 140 .uint32Param = OH_HUKS_AES_KEY_SIZE_256 141 }, { 142 .tag = OH_HUKS_TAG_PURPOSE, 143 .uint32Param = OH_HUKS_KEY_PURPOSE_DERIVE 144 }, { 145 .tag = OH_HUKS_TAG_KEY_ALIAS, 146 .blob = g_keyAliasFinal2001 147 }, { 148 .tag = OH_HUKS_TAG_PADDING, 149 .uint32Param = OH_HUKS_PADDING_NONE 150 }, { 151 .tag = OH_HUKS_TAG_BLOCK_MODE, 152 .uint32Param = OH_HUKS_MODE_CBC 153 } 154}; 155static const uint32_t ECDH_COMMON_SIZE = 1024; 156static struct OH_Huks_Blob g_keyAlias01001 = { 157 (uint32_t)strlen("HksECDHAgreeKeyAliasTest001_1"), 158 (uint8_t *)"HksECDHAgreeKeyAliasTest001_1" 159}; 160static struct OH_Huks_Blob g_keyAlias02001 = { 161 (uint32_t)strlen("HksECDHAgreeKeyAliasTest001_2"), 162 (uint8_t *)"HksECDHAgreeKeyAliasTest001_2" 163}; 164OH_Huks_Result MallocAndCheckBlobData( 165 struct OH_Huks_Blob *blob, 166 const uint32_t blobSize) 167{ 168 struct OH_Huks_Result ret; 169 ret.errorCode = OH_HUKS_SUCCESS; 170 blob->data = (uint8_t *)malloc(blobSize); 171 if (blob->data == NULL) { 172 ret.errorCode = OH_HUKS_ERR_CODE_INTERNAL_ERROR; 173 } 174 return ret; 175} 176/* 导出密钥 */ 177OH_Huks_Result HksEcdhAgreeExport(const struct OH_Huks_Blob *keyAlias1, const struct OH_Huks_Blob *keyAlias2, 178 struct OH_Huks_Blob *publicKey1, struct OH_Huks_Blob *publicKey2, const struct OH_Huks_ParamSet *genParamSet) 179{ 180 OH_Huks_Result ret = OH_Huks_ExportPublicKeyItem(keyAlias1, genParamSet, publicKey1); 181 if (ret.errorCode != OH_HUKS_SUCCESS) { 182 return ret; 183 } 184 ret = OH_Huks_ExportPublicKeyItem(keyAlias2, genParamSet, publicKey2); 185 if (ret.errorCode != OH_HUKS_SUCCESS) { 186 return ret; 187 } 188 return ret; 189} 190static const char *g_inData = "Hks_ECDH_Agree_Test_000000000000000000000000000000000000000000000000000000000000" 191 "00000000000000000000000000000000000000000000000000000000000000000000000000000000" 192 "0000000000000000000000000000000000000000000000000000000000000000000000000_string"; 193/* 协商密钥操作 */ 194OH_Huks_Result HksEcdhAgreeFinish(const struct OH_Huks_Blob *keyAlias, const struct OH_Huks_Blob *publicKey, 195 const struct OH_Huks_ParamSet *initParamSet, const struct OH_Huks_ParamSet *finishParamSet, struct OH_Huks_Blob *outData) 196{ 197 struct OH_Huks_Blob inData = { 198 (uint32_t)strlen(g_inData), 199 (uint8_t *)g_inData 200 }; 201 uint8_t handleU[sizeof(uint64_t)] = {0}; 202 struct OH_Huks_Blob handle = { sizeof(uint64_t), handleU }; 203 OH_Huks_Result ret = OH_Huks_InitSession(keyAlias, initParamSet, &handle, nullptr); 204 if (ret.errorCode != OH_HUKS_SUCCESS) { 205 return ret; 206 } 207 uint8_t outDataU[ECDH_COMMON_SIZE] = {0}; 208 struct OH_Huks_Blob outDataUpdate = { ECDH_COMMON_SIZE, outDataU }; 209 ret = OH_Huks_UpdateSession(&handle, initParamSet, publicKey, &outDataUpdate); 210 if (ret.errorCode != OH_HUKS_SUCCESS) { 211 return ret; 212 } 213 ret = OH_Huks_FinishSession(&handle, finishParamSet, &inData, outData); 214 if (ret.errorCode != OH_HUKS_SUCCESS) { 215 return ret; 216 } 217 return ret; 218} 219/* 协商密钥整体流程 */ 220static napi_value AgreeKey(napi_env env, napi_callback_info info) 221{ 222 struct OH_Huks_ParamSet *genParamSet = nullptr; 223 struct OH_Huks_ParamSet *initParamSet01 = nullptr; 224 struct OH_Huks_ParamSet *finishParamSet01 = nullptr; 225 struct OH_Huks_ParamSet *initParamSet02 = nullptr; 226 struct OH_Huks_ParamSet *finishParamSet02 = nullptr; 227 struct OH_Huks_Blob publicKey01 = { .size = OH_HUKS_ECC_KEY_SIZE_256, .data = nullptr }; 228 struct OH_Huks_Blob publicKey02 = { .size = OH_HUKS_ECC_KEY_SIZE_256, .data = nullptr }; 229 struct OH_Huks_Blob outData01 = { .size = ECDH_COMMON_SIZE, .data = nullptr }; 230 struct OH_Huks_Blob outData02 = { .size = ECDH_COMMON_SIZE, .data = nullptr }; 231 OH_Huks_Result ohResult; 232 do { 233 /* 1.确定密钥别名集成密钥参数集 */ 234 ohResult = InitParamSet(&genParamSet, g_genAgreeParams, sizeof(g_genAgreeParams) / sizeof(OH_Huks_Param)); 235 if (ohResult.errorCode != OH_HUKS_SUCCESS) { 236 break; 237 } 238 ohResult = InitParamSet(&initParamSet01, g_agreeParamsInit01, sizeof(g_agreeParamsInit01) / sizeof(OH_Huks_Param)); 239 if (ohResult.errorCode != OH_HUKS_SUCCESS) { 240 break; 241 } 242 ohResult = InitParamSet(&finishParamSet01, g_agreeParamsFinish01, 243 sizeof(g_agreeParamsFinish01) / sizeof(OH_Huks_Param)); 244 if (ohResult.errorCode != OH_HUKS_SUCCESS) { 245 break; 246 } 247 ohResult = InitParamSet(&initParamSet02, g_agreeParamsInit02, sizeof(g_agreeParamsInit02) / sizeof(OH_Huks_Param)); 248 if (ohResult.errorCode != OH_HUKS_SUCCESS) { 249 break; 250 } 251 ohResult = InitParamSet(&finishParamSet02, g_agreeParamsFinish02, 252 sizeof(g_agreeParamsFinish02) / sizeof(OH_Huks_Param)); 253 if (ohResult.errorCode != OH_HUKS_SUCCESS) { 254 break; 255 } 256 /* 2.设备A生成密钥 */ 257 ohResult = OH_Huks_GenerateKeyItem(&g_keyAlias01001, genParamSet, nullptr); 258 if (ohResult.errorCode != OH_HUKS_SUCCESS) { 259 break; 260 } 261 /* 3.设备B生成密钥 */ 262 ohResult = OH_Huks_GenerateKeyItem(&g_keyAlias02001, genParamSet, nullptr); 263 if (ohResult.errorCode != OH_HUKS_SUCCESS) { 264 break; 265 } 266 ohResult = MallocAndCheckBlobData(&publicKey01, publicKey01.size); 267 if (ohResult.errorCode != OH_HUKS_SUCCESS) { 268 break; 269 } 270 ohResult = MallocAndCheckBlobData(&publicKey02, publicKey02.size); 271 if (ohResult.errorCode != OH_HUKS_SUCCESS) { 272 break; 273 } 274 /* 4.设备A、B导出公钥 */ 275 ohResult = HksEcdhAgreeExport(&g_keyAlias01001, &g_keyAlias02001, &publicKey01, &publicKey02, genParamSet); 276 if (ohResult.errorCode != OH_HUKS_SUCCESS) { 277 break; 278 } 279 ohResult = MallocAndCheckBlobData(&outData01, outData01.size); 280 if (ohResult.errorCode != OH_HUKS_SUCCESS) { 281 break; 282 } 283 ohResult = MallocAndCheckBlobData(&outData02, outData02.size); 284 if (ohResult.errorCode != OH_HUKS_SUCCESS) { 285 break; 286 } 287 /* 5.设备A协商密钥 */ 288 ohResult = HksEcdhAgreeFinish(&g_keyAlias01001, &publicKey02, initParamSet01, finishParamSet01, &outData01); 289 if (ohResult.errorCode != OH_HUKS_SUCCESS) { 290 break; 291 } 292 /* 5.设备B协商密钥 */ 293 ohResult = HksEcdhAgreeFinish(&g_keyAlias02001, &publicKey01, initParamSet02, finishParamSet02, &outData02); 294 } while (0); 295 free(publicKey01.data); 296 free(publicKey02.data); 297 free(outData01.data); 298 free(outData02.data); 299 /* 6.设备A、B删除密钥 */ 300 OH_Huks_DeleteKeyItem(&g_keyAlias01001, genParamSet); 301 OH_Huks_DeleteKeyItem(&g_keyAlias02001, genParamSet); 302 OH_Huks_DeleteKeyItem(&g_keyAliasFinal1001, NULL); 303 OH_Huks_DeleteKeyItem(&g_keyAliasFinal2001, NULL); 304 OH_Huks_FreeParamSet(&genParamSet); 305 OH_Huks_FreeParamSet(&initParamSet01); 306 OH_Huks_FreeParamSet(&finishParamSet01); 307 OH_Huks_FreeParamSet(&initParamSet02); 308 OH_Huks_FreeParamSet(&finishParamSet02); 309 310 napi_value ret; 311 napi_create_int32(env, ohResult.errorCode, &ret); 312 return ret; 313} 314``` 315