OpenHarmony深度解读之分布式软总线:authmanager模块(4)/设备身份认证过程

一、概述

authmanager模块是鸿蒙为设备提供认证机制的模块。模块内的主要处理过程包括报文的接收、解密、再次封装、加密、发送的步骤。本文将继续介绍设备身份认证过程的细节。

二、源码分析

本文源代码主要是位于wifi_auth_manager.c文件中。

  1. 在函数OnDataReceived()中处理认证协议数据包负载部分。
rust 复制代码
/*
函数功能:处理接收到的认证协议数据包数据负载部分
函数参数:
    conn:认证设备连接信息结构体
    pkt:认证协议数据包头部结构体的地址
    data:数据负载部分的起始地址
函数返回值:无
详细:
*/
static void OnDataReceived(AuthConn *conn, const Packet *pkt, const char *data)
{
    SOFTBUS_PRINT("[AUTH] OnDataReceived\n");
    if ((pkt->module > MODULE_HICHAIN) && (pkt->module <= MODULE_AUTH_SDK)) {//如果module字段为MODULE_AUTH_SDK,则调用AuthInterfaceOnDataReceived继续进行处理。这里没有直接用==,是为了可扩展性
        AuthInterfaceOnDataReceived(conn, pkt->module, pkt->seq, data, pkt->dataLen);//若数据包类型为MODULE_AUTH_SDK,表示对端请求创建设备身份认证环境(暂定)
        return;
    }
    cJSON *msg = DecryptMessage(pkt->module, data, pkt->dataLen);//解密消息,返回cJSON结构体格式的数据
    if (msg == NULL) {
        SOFTBUS_PRINT("[AUTH] OnDataReceived DecryptMessage fail\n");
        return;
    }
    OnModuleMessageReceived(conn, pkt->module, pkt->flags, pkt->seq, msg);//根据数据包类型字段module,对接收到的cJSON数据选择不同的处理方式
    cJSON_Delete(msg);
    msg = NULL;
}

DD一下: 欢迎大家关注公众号<程序猿百晓生>,可以了解到一下知识点。

erlang 复制代码
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.鸿蒙版性能优化指南
.......
  1. 若数据包类型不属于MODULE_HICHAIN和MODULE_AUTH_SDK之间,则应是加密消息,首先进行解密,在函数DecryptMessage()中实现。
ini 复制代码
/*
函数功能:对接收到的消息进行解密
函数参数:
    module:数据包类型
    data:数据起始地址
    dataLen:数据长度
函数返回值:
    成功:返回解密后的cJSON格式的数据
    失败:返回NULL
详细:
*/
static cJSON *DecryptMessage(int module, const char *data, int dataLen)
{
    if (data == NULL) {
        return NULL;
    }
    if (!ModuleUseCipherText(module)) {//根据数据包类型判断该数据包负载部分是否加密
        return DecryptPlainMessage(data, dataLen);//若是明文传输,则直接解析为cJSON结构体格式的数据
    }
    if (dataLen < MESSAGE_ENCRYPT_OVER_HEAD_LEN) {//检查数据包是否合法
        return NULL;
    }
    int index = GetKeyIndex(data, 0, MESSAGE_INDEX_LEN);//解析会话密钥索引
    SessionKey *sKey = AuthGetSessionKeyByIndex(index);//根据会话密钥索引查找并获取会话密钥
    if (sKey == NULL) {
        SOFTBUS_PRINT("[AUTH] DecryptMessage get session key fail\n");
        return NULL;
    }
    unsigned int len = dataLen - MESSAGE_ENCRYPT_OVER_HEAD_LEN + 1;//获取数据包实际有效负载长度(即加密部分的长度)
    unsigned char *output = malloc(len);//申请解密后的数据存储空间
    if (output == NULL) {
        return NULL;
    }
    if (memset_s((void *)output, len, 0, len) != EOK) {
        free(output);
        output = NULL;
        return NULL;
    }
    AesGcmCipherKey cipherKey = {0};//定义一个临时会话密钥
    cipherKey.keybits = GCM_KEY_BITS_LEN_128;//密钥长度为128位
    int ret = memcpy_s(cipherKey.key, SESSION_KEY_LENGTH, sKey->key, AUTH_SESSION_KEY_LEN);//初始化密钥
    ret += memcpy_s(cipherKey.iv, IV_LEN, data + MESSAGE_INDEX_LEN, IV_LEN);//初始化IV
    if (ret != 0) {
        free(output);
        output = NULL;
        return NULL;
    }
    ret = DecryptTransData(&cipherKey,
        (unsigned char*)&data[MESSAGE_INDEX_LEN], dataLen - MESSAGE_INDEX_LEN, output, len);//解密,结果保存在output缓冲区中
    if (ret <= 0) {
        SOFTBUS_PRINT("[AUTH] DecryptMessage DecryptTransData fail\n");
        free(output);
        output = NULL;
        return NULL;
    }
    cJSON *msg = cJSON_Parse((char*)output);//将output中字符串格式的json数据转换为cJSON结构体
    free(output);
    output = NULL;
    return msg;
}
  1. 根据数据包类型字段module,对接收到的cJSON数据选择不同的处理方式,在函数OnModuleMessageReceived()中实现。
arduino 复制代码
/*
函数功能:根据数据包类型字段module,对接收到的cJSON数据选择不同的处理方式
函数参数:
    conn:认证设备连接信息
    module:数据包类型
    flags:数据包头部标记
    seq:数据包序列号
    msg:cJSON数据
函数返回值:无
详细:
*/
static void OnModuleMessageReceived(AuthConn *conn, int module, int flags, long long seq, const cJSON *msg)
{
    switch (module) {
        case MODULE_TRUST_ENGINE: {//如果是MODULE_TRUST_ENGINE类型,表明是可信设备
            if (((unsigned int)flags & FLAG_REPLY) == 0) {//如果此数据包不是"回复数据包",那么表明对端是请求端
                OnMsgOpenChannelReq(conn, seq, msg);//处理请求消息
            }
            break;
        }
        case MODULE_CONNECTION: {//如果是MODULE_CONNECTION类型,表明是连接设备
            OnMessageReceived(conn, seq, msg);//处理接收到的消息,解析并按规则回复给对端
            break;
        }
        default: {
            break;
        }
    }
    return;
}
相关推荐
kyle~1 分钟前
电控---CMSIS概览
嵌入式·通信·电控
川石教育3 小时前
鸿蒙开发之嵌套对象更新
harmonyos·鸿蒙开发·鸿蒙开发培训·鸿蒙开发教程·鸿蒙培训课程
掘金-我是哪吒8 小时前
分布式微服务系统架构第105集:协议,高性能下单系统示例项目
分布式·微服务·架构·系统架构·linq
风铃儿~9 小时前
Java微服务注册中心深度解析:环境隔离、分级模型与Eureka/Nacos对比
java·分布式·微服务·面试
猫霸11 小时前
WPF静态资源StaticResource和动态资源DynamicResource有什么区别,x:Static又是什么意思?
分布式·c#·.net·wpf
kinlon.liu13 小时前
使用Redis实现分布式限流
数据库·redis·分布式·缓存
冉冉同学15 小时前
【HarmonyOS NEXT】解决微信浏览器无法唤起APP的问题
android·前端·harmonyos
别说我什么都不会15 小时前
【仓颉三方库】 数据库驱动——kv4cj
harmonyos
进击的圆儿17 小时前
鸿蒙应用(医院诊疗系统)开发篇2·Axios网络请求封装全流程解析
华为·harmonyos