一、概述
上一篇博客 OpenHarmony解读之设备认证:数据接收管理-获取HiChain实例(2) 介绍的主要内容是构建本端的长期保存的密钥对,即重点是对函数build_self_lt_key_pair的总体分析,在上文中讲到该函数通过回调函数的方式调用位于分布式软总线模块的AuthGetProtocolParams函数进行协议参数的获取,主要是获取密钥长度、对端认证id和本端认证id。本文将继续分析build_self_lt_key_pair函数的其余内容。
二、源码分析
这一模块的源码位于:/base/security/deviceauth。
- 继上文,如果在函数AuthGetProtocolParams中成功获取到本端认证id,则将继续处理,否则就返回。在成功获取到本端认证id的情况下,接着调用generate_service_id函数进行处理,该函数的具体分析如下:
/*
函数功能:利用会话标识符的HC包名称和HC服务类型通过sha256哈希算法计算出哈希值,作为服务id
函数参数:
identity:会话标识,包括会话id、HC包名称、HC服务类型以及上下文信息
函数返回值:
成功:返回赋值后的服务id结构体
失败:返回空的服务id结构体
详细:
//服务id结构:
struct service_id {
uint32_t length;//长度
uint8_t service_id[HC_SERVICE_ID_BUFF_LEN];//服务id数组
};
//sha256哈希值结构:
struct sha256_value {
uint32_t length;//长度
uint8_t sha256_value[HC_SHA256_LEN];//value
};
*/
struct service_id generate_service_id(const struct session_identity *identity)
{
struct service_id service_id;//定义一个service_id局部变量
(void)memset_s(&service_id, sizeof(service_id), 0, sizeof(service_id));//清空service_id地址空间
if (identity == NULL) {//参数有效性检查
LOGE("Input is null");
return service_id;
}
uint32_t pack_name_len = identity->package_name.length;//获取HC包名称长度
if ((pack_name_len == 0) || (pack_name_len > HC_PACKAGE_NAME_BUFF_LEN)) {//若长度为0或者HC_PACKAGE_NAME_BUFF_LEN,则直接返回空service_id
LOGE("Pack name length is: %u", pack_name_len);//日志信息
return service_id;
}
uint32_t type_len = identity->service_type.length;//获取HC服务类型长度
if ((type_len == 0) || (type_len > HC_SERVICE_TYPE_BUFF_LEN)) {//若长度为0或者HC_SERVICE_TYPE_BUFF_LEN,则直接返回空service_id
LOGE("Service type length is: %u", type_len);//日志信息
return service_id;
}
uint32_t srv_len = type_len + pack_name_len;//定义srv_len保存HC服务类型长度与HC包名称长度之和
struct uint8_buff id_buff = {//初始化一个按字节存储的缓冲区,用于保存HC包名称和HC服务类型
.length = srv_len,
.size = srv_len
};
id_buff.val = (uint8_t *)MALLOC(srv_len);//为该缓冲区申请内存空间
if (id_buff.val == NULL) {//若申请失败则直接返回
LOGE("Malloc mem failed");
return service_id;//返回空service_id
}
/*将HC包名称和HC服务类型依次拷贝到id_buff指向的缓冲区*/
if (memcpy_s(id_buff.val, srv_len, identity->package_name.name, pack_name_len) != EOK) {//将HC包名称拷贝到id_buff指向的缓冲区
LOGE("Copy service id buff failed");//拷贝失败,打印日志信息
safe_free(id_buff.val);//释放内存
return service_id;//返回空service_id
}
if (memcpy_s(id_buff.val + pack_name_len, srv_len - pack_name_len, identity->service_type.type, type_len) != EOK) {//将HC服务类型拷贝到id_buff指向的缓冲区
LOGE("Copy service id buff failed");//拷贝失败,打印日志信息
safe_free(id_buff.val);//释放内存
return service_id;//返回空service_id
}
struct sha256_value srv_sha256 = sha256(&id_buff);//通过sha256算法计算出HC包名称和HC服务类型的哈希值保存在srv_sha256中
safe_free(id_buff.val);//释放内存空间
id_buff.val = NULL;
if (srv_sha256.length > 0) {//成功计算出哈希值
if (memcpy_s(service_id.service_id, HC_SERVICE_ID_BUFF_LEN, srv_sha256.sha256_value, HC_SHA256_LEN) == EOK) {//将计算出的哈希值拷贝到服务id的结构体中
service_id.length = srv_sha256.length;//赋值服务id长度
} else {
LOGE("Copy hash value failed");
}
}
return service_id;
}
DD一下:欢迎大家关注公众号<程序猿百晓生>,可以了解到一下知识点。
`欢迎大家关注公众号<程序猿百晓生>,可以了解到一下知识点。`
1.OpenHarmony开发基础
2.OpenHarmony北向开发环境搭建
3.鸿蒙南向开发环境的搭建
4.鸿蒙生态应用开发白皮书V2.0 & V3.0
5.鸿蒙开发面试真题(含参考答案)
6.TypeScript入门学习手册
7.OpenHarmony 经典面试题(含参考答案)
8.OpenHarmony设备开发入门【最新版】
9.沉浸式剖析OpenHarmony源代码
10.系统定制指南
11.【OpenHarmony】Uboot 驱动加载流程
12.OpenHarmony构建系统--GN与子系统、部件、模块详解
13.ohos开机init启动流程
14.鸿蒙版性能优化指南
.......
- 在函数generate_service_id中,调用了sha256函数,对该函数的具体分析如下:
/*
函数功能:执行sha256哈希算法,以uint8_buff缓冲区的消息为输入,计算出哈希值value,再封装成sha256_value结构返回
函数参数:
message:执行哈希的数据
函数返回值:
成功:返回sha256_value结构体变量,即计算出的哈希值
失败:返回空的sha256_value
详细:本函数实则是在hks_hash接口之上做了一层封装,主要是使用sha256哈希算法计算哈希值。
*/
static struct sha256_value sha256(const struct uint8_buff *message)
{
struct sha256_value sha256_value;//定义sha256_value结构体变量以保存计算出的哈希值
(void)memset_s(&sha256_value, sizeof(sha256_value), 0, sizeof(sha256_value));//清空该结构体变量空间
struct hks_blob src_data = {//初始化源数据块
.data = message->val,//实际数据地址
.size = message->length,//数据长度
.type = HKS_BLOB_TYPE_RAW
};
struct hks_blob hash;//定义一个hash数据块,用于保存计算出的哈希值及其长度
(void)memset_s(&hash, sizeof(hash), 0, sizeof(hash));//清空该结构体变量空间
hash.data = (uint8_t *)MALLOC(HC_SHA256_LEN * sizeof(uint8_t));//申请地址空间以保存数据
if (hash.data == NULL) {
LOGE("SHA256 malloc failed");//申请空间失败,打印日志
return sha256_value;//返回空的sha256_value
}
hash.size = HC_SHA256_LEN;//赋值哈希值的长度为sha256算法的哈希值长度,单位为字节
int32_t hks_status = hks_hash(HKS_ALG_HASH_SHA_256, &src_data, &hash);//调用hks_hash接口根据src_data计算出哈希值,保存在hash中
if ((hks_status == 0) && (hash.size == HC_SHA256_LEN)) {//执行成功
(void)memcpy_s(sha256_value.sha256_value, sizeof(sha256_value.sha256_value), hash.data, HC_SHA256_LEN);//将计算出的哈希值拷贝到sha256_value变量空间中
sha256_value.length = HC_SHA256_LEN;//赋值哈希值长度32byte
} else {
LOGE("SHA256 failed, status=%d", hks_status);//执行失败则打印状态
sha256_value.length = 0;
}
safe_free(hash.data);//释放hash.data内存空间
return sha256_value;
}
三、小结
本文主要介绍了在生成本端长期保存的密钥对过程中,服务id的生成过程,在下一篇博客中将介绍密钥别名的生成过程,敬请期待!