OpenHarmony解读之设备认证:HiChain消息处理全解析(1)

📌往期推文全新看点(文中附带最新·鸿蒙全栈学习笔记)

①📖 鸿蒙应用开发与鸿蒙系统开发哪个更有前景?

②📖嵌入式开发适不适合做鸿蒙南向开发?看完这篇你就了解了~

③📖 对于大前端开发来说,转鸿蒙开发究竟是福还是祸?

④📖 鸿蒙岗位需求突增!移动端、PC端、IoT到底该怎么选?

⑤📖 记录一场鸿蒙开发岗位面试经历~

⑥📖 持续更新中……


一、概述

本文将承接上一篇博客 OpenHarmony解读之设备认证:数据接收管理-消息解析 的内容,主要介绍HiChain本端接收数据的处理过程中的消息处理阶段

二、源码分析

这一模块的源码位于:/base/security/deviceauth。

  1. receive_data函数中,首先执行deserialize_message函数将消息解析完毕保存在struct message结构中,然后调用navigate_message函数,根据消息码得到消息类型msg_type和消息模块modular,具体分析如下:
//导航消息,得到 "消息模块-消息类型(消息码低四位)-是否请求消息" 一一对应
struct header_analysis navigate_message(uint32_t message_code)
{
    struct header_analysis nav = { INVALID_MODULAR, 0, 0 };
    for (uint32_t i = 0; i < sizeof(G_MESSAGE_CODE_MAP) / sizeof(G_MESSAGE_CODE_MAP[0]); i++) {//sizeof(G_MESSAGE_CODE_MAP) / sizeof(G_MESSAGE_CODE_MAP[0])表示消息码数组的元素个数
        if (G_MESSAGE_CODE_MAP[i].code == message_code) {//根据消息码查表,如果存在,就进行相关数据更新
            nav.modular = G_MESSAGE_CODE_MAP[i].modular;//赋予消息模块
            nav.msg_type = message_code & 0xf; /* message_code & 0xf get low four bits of message code 获取低四位的消息码作为msg_type*/
            nav.is_request_msg = G_MESSAGE_CODE_MAP[i].is_request_msg;
            break;
        }
    }
    LOGI("Message code %u, nav is %d, %d, %d", message_code, nav.modular, nav.msg_type, nav.is_request_msg);
    return nav;
}
  1. 然后执行check_message_support函数检查消息是否可支持,对该函数的分析如下:
/*
函数功能:检查消息是否是系统可支持
函数参数:
    hichain:HiChain实例
    nav:导航消息头
    receive:解析后的消息
函数返回值:
    成功:返回0
    失败:返回错误码
详细:将解析出来的操作码保存到hichain中且与消息码对应正确,一致
*/
int32_t check_message_support(struct hichain *hichain, const struct header_analysis *nav,
    const struct message *receive)
{
    if (nav->modular == 0) {//表示未知消息
        LOGE("Receive unknow message, message code is 0x%04x", receive->msg_code);
        return HC_UNKNOW_MESSAGE;
    }
    if (!check_hichain_state_is_success(hichain, nav)) {//检查hichain实例的状态是否正确
        return HC_STATE_ERROR;
    }
    int32_t operation_code = get_operation_code(nav, receive);//根据消息模块类型获取解析不同协议的操作码,这里有PAKE和STS协议
    if (operation_code == INVALID_OPERATION_CODE) {//如果操作码无效,则返回错误码
        return HC_OPERATION_CODE_ERROR;
    } else if (operation_code == NO_OPERATION_CODE) {//如果操作码为0,表示“无操作”
        /* compare with recorded operation code and verify */
        if (is_message_illegal(hichain->operation_code, nav->modular)) {//判断消息是否属于非法消息
            LOGE("Operation code is %d, message code is %u, it is inconsistency",
                hichain->operation_code, receive->msg_code);
            return HC_MESSAGE_INCONSISTENCY;//返回'消息不一致'的代码
        }
    } else {//如果是其他操作码
        int32_t ret = hichain->cb.confirm_receive_request(&hichain->identity, operation_code);//确认收到的请求,调用HC回调函数处理,目前版本暂不可用
        if (ret != 0) {
            LOGE("Service does not allow response %d", operation_code);
            return HC_SERVICE_CONFIRM_ERROR;
        }
        hichain->operation_code = operation_code;
    }
    return HC_OK;
}
  1. 在函数check_message_support中:首先执行check_hichain_state_is_success函数检查hichain实例的状态是否正确,具体函数分析如下:
//检查hichain实例的状态是否正确,成功返回true,失败返回false
static bool check_hichain_state_is_success(struct hichain *hichain, const struct header_analysis *nav)
{
    if ((nav->modular == PAKE_MODULAR) || (nav->modular == STS_MODULAR)) {//如果消息属于PAKE协议或者STS协议的消息,则判断其状态是否是初始化状态和密钥协商状态
        if ((hichain->state != INIT_STATE) && (hichain->state != KEY_AGREEMENT_STATE) &&
            (hichain->last_state != INIT_STATE) && (hichain->last_state != KEY_AGREEMENT_STATE)) {//如果状态不是初始化状态和密钥协商状态,返回失败
            goto error;
        }
    } else {//如果属于其他类型的消息,则判断其状态是否是密钥协商状态和操作状态
        if ((hichain->state != KEY_AGREEMENT_STATE) && (hichain->state != OPERATION_STATE) &&
            (hichain->last_state != KEY_AGREEMENT_STATE) && (hichain->last_state != OPERATION_STATE)) {
            goto error;//如果状态不是密钥协商状态和运行状态,返回失败
        }
    }
    return true;//返回正确
error:
    LOGE("Check hichain state failed, state is %d, message nav is %d-%d-%d", hichain->state, nav->modular,
        nav->msg_type, nav->is_request_msg);//处理错误,打印错误日志信息
    return false;//返回错误
}
  1. 然后执行get_operation_code函数获取操作码:
static int32_t get_operation_from_pake(void *payload);//函数声明
static int32_t get_operation_from_sts(void *payload);//函数声明
//根据消息模块类型获取解析不同协议的操作码,这里有PAKE和STS协议
static int32_t get_operation_code(const struct header_analysis *nav, const struct message *receive)
{
    int32_t operation_code = NO_OPERATION_CODE;//初始化为无操作
    if ((nav->modular == PAKE_MODULAR) && (nav->msg_type == PAKE_START_MSG) && nav->is_request_msg) {//如果消息属于PAKE协议,且是"请求开始"消息,则获取PAKE协议的操作码
        operation_code = get_operation_from_pake(receive->payload);//获取解析出的pake协议的操作码
    } else if ((nav->modular == STS_MODULAR) && (nav->msg_type == STS_START_MSG) && nav->is_request_msg) {//如果消息属于STS协议,且是"请求开始"消息,则获取STS协议的操作码
        operation_code = get_operation_from_sts(receive->payload);//获取解析出的sts协议的操作码
    }
    LOGI("Receive message had operation code is %d", operation_code);
    return operation_code;
}
//获取解析出的pake协议的操作码
static int32_t get_operation_from_pake(void *payload)
#if !(defined(_CUT_PAKE_) || defined(_CUT_PAKE_SERVER_))
{
    int32_t permissible_code[] = { BIND, AUTH_KEY_AGREEMENT };//允许的操作码,目前有:BIND(绑定),AUTH_KEY_AGREEMENT(认证密钥协商)
    struct pake_start_request_data *data = payload;//结构体强转,解析出该消息的操作码
    for (uint32_t i = 0; i < sizeof(permissible_code) / sizeof(int32_t); i++) {
        if (permissible_code[i] == data->operation_code) {//查询该操作码是否属于允许的操作码,是就返回,否则返回无效,即-1
            return data->operation_code;
        }
    }
    LOGE("Receive operation code %d is error", data->operation_code);
    return INVALID_OPERATION_CODE;
}
//获取解析出的sts协议的操作码
static int32_t get_operation_from_sts(void *payload)
#if !(defined(_CUT_STS_) || defined(_CUT_STS_SERVER_))
{
    int32_t permissible_code[] = { AUTHENTICATE, ADD_AUTHINFO, REMOVE_AUTHINFO, UNBIND, SEC_CLONE_OP };//允许的操作码,
    struct sts_start_request_data *data = payload;//结构体强转,解析出该消息的操作码
    for (uint32_t i = 0; i < sizeof(permissible_code) / sizeof(int32_t); i++) {//查询该操作码是否属于允许的操作码,是就返回,否则返回无效,即-1
        if (permissible_code[i] == data->operation_code) {
            return data->operation_code;
        }
    }
    LOGE("Receive operation code %d is error", data->operation_code);
    return INVALID_OPERATION_CODE;
}
  1. 接着执行is_message_illegal函数检查消息是否合法:
//检查消息是否为非法消息,是非法消息则返回true,否则返回false
static bool is_message_illegal(int32_t operation_code, int32_t modular)
{
    //合法消息表
    struct check_message_powered table[] = { { BIND, PAKE_MODULAR },
                                             { BIND, EXCHANGE_MODULAR },
                                             { AUTH_KEY_AGREEMENT, PAKE_MODULAR },
                                             { UNBIND, STS_MODULAR },
                                             { UNBIND, REMOVE_MODULAR },
                                             { AUTHENTICATE, STS_MODULAR },
                                             { ADD_AUTHINFO, STS_MODULAR },
                                             { ADD_AUTHINFO, ADD_MODULAR },
                                             { REMOVE_AUTHINFO, STS_MODULAR },
                                             { REMOVE_AUTHINFO, REMOVE_MODULAR },
                                             { SEC_CLONE_OP, STS_MODULAR },
                                             { SEC_CLONE_OP, SEC_CLONE_MODULAR } };
    for (uint32_t i = 0; i < sizeof(table) / sizeof(table[0]); i++) {//遍历合法消息表,查询对应的消息是否存在
        if ((modular == table[i].modular) && (operation_code == table[i].operation_code)) {
            return false;//若存在,返回消息合法
        }
    }
    return true;//不存在,返回消息不合法
}

三、小结

本文主要介绍了导航消息模块和检查消息合法性模块,其余内容将在下一篇博客中介绍。

<think>好的,我现在需要帮助用户解决关于OpenHarmony中出现的错误日志问题:openharmony [I][devicemanagerserviceimpl][onError]:HichainAuthenCallBack::onError reqId:5897755440, operation:0, errorCode:4098。 首先,我需要理解用户的问题。用户之前询问过HUKS的错误码-13,现在遇到了另一个错误码4098,涉及HichainAuthenCallBack。这可能是在设备管理或分布式身份认证过程中出现的错误。用户可能是开发者,在开发过程中遇到了这个错误,需要了解错误原因和解决方法。 接下来,我需要确定错误码4098的含义。在OpenHarmony中,Hichain属于分布式身份认证模块,错误码可能有特定的定义。根据经验,4098可能对应某种身份验证失败的情况,比如密钥协商失败、证书问题、网络问题或者权限不足。需要查阅相关文档或源代码确认错误码的具体含义,但假设暂时无法访问文档,只能根据常见情况进行推断。 然后,分析可能的原因。首先考虑密钥协商失败,Hichain设备间建立安通道时可能因为密钥不匹配或过期导致失败。其次,证书问题,比如设备证书无效、过期或未正确安装。网络问题也可能导致设备间通信失败,比如连接不稳定或超时。权限问题,比如应用缺少必要的权限,如ACCESS_HUKS或ACCESS_SERVICE_DM。参数错误,调用API时传入了错误的参数,如reqId或operation的值不符合要求。此外,兼容性问题,设备间的Hichain协议版本不一致也可能导致错误。 接下来,解决方案需要分步骤。首先确认错误码定义,查看官方文档或头文件,比如hichain_errno.h。检查设备间网络连接是否正常,尝试ping或检查防火墙设置。验证设备证书是否有效,重新生成或更新证书。检查权限配置,确保应用有必要的权限声明。核对API调用参数,确保reqId和operation值正确。更新系统和Hichain相关组件到最新版本,确保兼容性。增加错误处理逻辑,捕获异常并记录详细信息。 扩展说明部分需要解释Hichain的作用,如设备身份认证和数据加密传输,帮助用户理解上下文。错误处理建议则给出代码示例,展示如何捕获并处理错误,方便用户参考。 最后,用户可能需要的不仅是错误码的解释,还有具体的解决步骤和预防措施。需要确保回答结构清晰,逐步引导用户排查问题,并提供代码示例和文档链接,帮助用户进一步自主解决问题。同时提醒用户提供更多上下文信息,以便更精确地定位问题。</think>在 OpenHarmony分布式能力中,`HichainAuthenCallBack::onError` 是设备认证失败时的回调接口。错误码 **4098** 表示设备间身份认证或密钥协商过程中出现异常,以下是详细分析及解决方案: --- ### **1. 错误码 4098 的典型含义** 根据 Hichain 模块的常见错误码定义,**4098** 通常与 **密钥协商失败** 或 **身份认证流程中断** 相关,可能原因包括: - 设备间的密钥交换协议不匹配 - 证书校验失败(如证书过期、签名无效) - 网络通信异常导致认证流程中断 - 权限不足或参数传递错误 --- ### **2. 关键字段解析** - **reqId: 5897755440**:标识当前认证请求的唯一 ID,可用于追踪日志中的完整流程。 - **operation: 0**:表示操作类型(如 `0` 可能对应密钥协商阶段)。 - **errorCode: 4098**:具体错误原因(需结合 Hichain 模块错误码表确认)。 --- ### **3. 常见原因及排查步骤** #### **(1) 密钥协商失败** - **设备间密钥参数不一致** 检查参与认证设备是否使用相同的密钥算法(如 ECC、RSA)和参数(如密钥长度)。 - **证书链不完整或过期** 验证设备证书的有效性,确保证书链完整且未过期。 #### **(2) 网络通信问题** - **设备间网络未连通** 确保设备处于同一局域网,且防火墙未拦截端口(Hichain 默认使用 8000-8100 端口)。 - **通信超时** 增加超时阈值(通过 `setTimeout` 接口调整)。 #### **(3) 权限或参数错误** - **缺少权限声明** 在 `module.json5` 中添加分布式权限: ```json { "module": { "requestPermissions": [ { "name": "ohos.permission.ACCESS_SERVICE_DM" }, { "name": "ohos.permission.ACCESS_HUKS" } ] } } ``` - **参数传递错误** 检查 `reqId` 生成逻辑和 `operation` 类型是否合法。 --- ### **4. 解决方案** #### **步骤 1:验证密钥协商参数** 确保两端设备使用相同的密钥配置: ```typescript import distributedDeviceManager from '@ohos.distributedDeviceManager'; // 示例:初始化设备认证参数 let authParam: distributedDeviceManager.AuthParam = { authType: distributedDeviceManager.AuthType.SAME_ACCOUNT, // 认证类型 keyAlgorithm: distributedDeviceManager.KeyAlgorithm.ECC, // 密钥算法 keySize: 256, // 密钥长度 // 其他参数需与对端设备一致 }; ``` #### **步骤 2:检查证书有效性** ```typescript import hiChain from '@ohos.security.hichain'; // 示例:验证本地证书 hiChain.verifyLocalCertificate() .then(() => { console.log('证书有效'); }) .catch((error) => { console.error('证书验证失败:', error.code); }); ``` #### **步骤 3:捕获错误并重试** ```typescript import hiChain from '@ohos.security.hichain'; // 示例:处理认证错误 class AuthCallback { onError(reqId: number, operation: number, errorCode: number) { console.error(`认证失败 reqId=${reqId}, operation=${operation}, code=${errorCode}`); if (errorCode === 4098) { // 根据错误码执行重试或回退逻辑 this.retryAuthentication(reqId); } } private retryAuthentication(reqId: number) { hiChain.retryAuth(reqId) .then(() => { console.log('重试成功'); }) .catch((error) => { console.error('重试失败:', error.code); }); } } ``` --- ### **5. 扩展说明** - **Hichain 认证流程**: Hichain 负责设备间的互信认证和密钥协商,是分布式数据共享和安通信的基础。 - **错误码文档参考**: 查阅 OpenHarmony 源码中的错误码定义文件: [hichain_errno.h](https://gitee.com/openharmony/security_hichain/blob/master/interfaces/innerkits/hichain_c/include/hichain_errno.h) --- ### **6. 调试建议** 1. **日志过滤** 使用 `hilog` 过滤 `reqId=5897755440` 的完整流程日志: ```bash hilog | grep 5897755440 ``` 2. **网络诊断** 检查设备间能否互相 ping 通,并确认端口开放状态。 若问题仍未解决,建议提供完整的认证初始化代码和日志片段,以便进一步分析。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值