Hash算法¶
Copyright © Quectel Wireless Solutions Co., Ltd. 2026. All rights reserved.
功能概述¶
本模块提供标准的消息摘要(Hash)计算功能,支持SHA-1、SHA-256和MD5算法,可用于数据完整性校验、密码加盐散列存储,以及基于HMAC(散列消息认证码)的API鉴权防篡改。
主要应用场景¶
文件完整性校验:下载OTA固件后计算其SHA-256摘要,与云端提供的摘要比对,判断文件是否损坏或被篡改。
报文完整性校验:对通信数据计算Hash值,确认传输前后内容一致。
HMAC身份认证:使用密钥对消息计算HMAC-SHA256签名,供云端与设备双方校验请求是否合法。
密码保护:不直接保存明文密码,而是保存经专用密码哈希算法处理后的结果;嵌入式设备常用PBKDF2-HMAC-SHA256。
密钥派生:通过ECDH得到共享秘密后,使用HKDF-SHA256派生AES会话密钥。
数字签名:RSA/ECDSA通常先对固件或数据计算SHA-256摘要,再对摘要进行签名。
数据去重与版本识别:通过比较文件的Hash值判断两个文件内容是否相同。
常见问题¶
Hash不是加密算法:Hash运算不可逆,无法"解密",主要用于完整性校验和摘要计算。
密码不能直接用SHA-256存储:保存密码应使用Argon2、bcrypt、scrypt或PBKDF2等专用算法,并加入随机盐。
身份认证不能只用普通Hash:消息防篡改应使用HMAC-SHA256,不能以"密钥拼接数据后直接计算SHA-256"的方式代替。
避免使用MD5/SHA-1:安全场景应优先选用SHA-256/SHA-3;比较摘要时应使用恒定时间比较,避免时序信息泄露。
Hash算法 API¶
头文件¶
qcm_sha256.h
函数概览¶
函数 |
说明 |
|---|---|
qcm_core_sha256() |
一次性计算输入数据的SHA-256摘要 |
qcm_hmac_sha256() |
一次性计算数据的HMAC-SHA256认证码 |
qcm_sha256_init() |
初始化SHA-256流式计算上下文 |
qcm_sha256_starts() |
启动或重置流式计算 |
qcm_sha256_update() |
追加处理一段输入数据 |
qcm_sha256_finish() |
结束流式计算并输出32字节摘要 |
qcm_sha256_free() |
释放SHA-256上下文并清除敏感数据 |
函数详解¶
qcm_core_sha256¶
功能描述
一次性计算输入数据的SHA-256摘要。适用于长度较小且已知的数据,将任意长度的输入直接散列为32字节的摘要结果。系统同时提供宏别名 qcm_sha256(),两者功能完全一致。函数原型
void qcm_core_sha256(const qosa_uint8_t *input, qosa_uint32_t ilen, qosa_uint8_t output[32]);
参数说明
参数名 |
输入/输出 |
类型 |
说明 |
|---|---|---|---|
input |
输入 |
const qosa_uint8_t * |
待计算数据的缓冲区首地址 |
ilen |
输入 |
qosa_uint32_t |
输入数据的长度;单位:字节 |
output |
输出 |
qosa_uint8_t[32] |
存放32字节摘要结果的输出数组 |
返回值说明
无
qcm_hmac_sha256¶
功能描述
基于SHA-256计算HMAC(密钥散列消息认证码)。常用于调用云平台API时,对密钥与请求报文联合运算生成鉴权签名,防止请求内容被篡改。函数原型
void qcm_hmac_sha256(const qosa_uint8_t *msg,
qosa_uint32_t msg_len,
const qosa_uint8_t *key,
qosa_uint32_t key_len,
qosa_uint8_t output[32]);
参数说明
参数名 |
输入/输出 |
类型 |
说明 |
|---|---|---|---|
msg |
输入 |
const qosa_uint8_t * |
待认证消息的缓冲区首地址 |
msg_len |
输入 |
qosa_uint32_t |
消息长度;单位:字节 |
key |
输入 |
const qosa_uint8_t * |
鉴权密钥的缓冲区首地址 |
key_len |
输入 |
qosa_uint32_t |
密钥长度;单位:字节 |
output |
输出 |
qosa_uint8_t[32] |
存放32字节认证码结果的输出数组 |
返回值说明
无
qcm_sha256_init¶
功能描述
初始化SHA-256流式计算上下文,为流式计算做准备。流式计算流程的第一步。函数原型
void qcm_sha256_init(qcm_core_sha256_context_t *ctx);
参数说明
参数名 |
输入/输出 |
类型 |
说明 |
|---|---|---|---|
ctx |
输出 |
*qcm_core_sha256_context_t ** |
待初始化的上下文;详见 qcm_core_sha256_context_t |
返回值说明
无
qcm_sha256_starts¶
功能描述
启动或重置流式计算。若上下文中存有此前的计算状态,将被重置。函数原型
void qcm_sha256_starts(qcm_core_sha256_context_t *ctx);
参数说明
参数名 |
输入/输出 |
类型 |
说明 |
|---|---|---|---|
ctx |
输入/输出 |
*qcm_core_sha256_context_t ** |
已初始化的上下文;详见 qcm_core_sha256_context_t |
返回值说明
无
qcm_sha256_update¶
功能描述
追加处理一段输入数据。可循环多次调用,将超出内存容量的大文件分段送入计算。函数原型
void qcm_sha256_update(qcm_core_sha256_context_t *ctx, const qosa_uint8_t *input, qosa_uint32_t ilen);
参数说明
参数名 |
输入/输出 |
类型 |
说明 |
|---|---|---|---|
ctx |
输入/输出 |
*qcm_core_sha256_context_t ** |
已完成启动的上下文;详见 qcm_core_sha256_context_t |
input |
输入 |
const qosa_uint8_t * |
本次追加数据的缓冲区首地址 |
ilen |
输入 |
qosa_uint32_t |
本次追加数据的长度;单位:字节 |
返回值说明
无
qcm_sha256_finish¶
功能描述
结束流式计算,输出最终的32字节摘要,内部自动完成数据补位。函数原型
void qcm_sha256_finish(qcm_core_sha256_context_t *ctx, qosa_uint8_t output[32]);
参数说明
参数名 |
输入/输出 |
类型 |
说明 |
|---|---|---|---|
ctx |
输入/输出 |
*qcm_core_sha256_context_t ** |
当前计算的上下文;详见 qcm_core_sha256_context_t |
output |
输出 |
qosa_uint8_t[32] |
存放32字节摘要结果的输出数组 |
返回值说明
无
qcm_sha256_free¶
功能描述
释放SHA-256上下文,擦除其中的内部状态与敏感数据,防止残留数据被误用。函数原型
void qcm_sha256_free(qcm_core_sha256_context_t *ctx);
参数说明
参数名 |
输入/输出 |
类型 |
说明 |
|---|---|---|---|
ctx |
输入/输出 |
*qcm_core_sha256_context_t ** |
计算完成后待清理的上下文;详见 qcm_core_sha256_context_t |
返回值说明
无
结构体定义¶
qcm_core_sha256_context_t¶
SHA-256流式计算上下文结构体定义如下:
typedef struct
{
qosa_uint32_t total[2];
qosa_uint32_t state[8];
qosa_uint8_t buffer[64];
qosa_uint8_t is224;
} qcm_core_sha256_context_t;
参数 |
类型 |
说明 |
|---|---|---|
total |
qosa_uint32_t[2] |
已处理数据的总长度计数器;单位:字节 |
state |
qosa_uint32_t[8] |
哈希运算的中间状态 |
buffer |
qosa_uint8_t[64] |
暂存不足64字节的末尾数据,供后续运算或结束时补位处理 |
is224 |
qosa_uint8_t |
算法选择标志 |
应用逻辑流程图¶
示例代码¶
常规短文本摘要计算(一次性计算):
#include "qcm_sha256.h"
#include "qosa_sys.h"
void app_sha_demo_short() {
qosa_uint8_t input_msg[] = "Hello_UniRTOS_2026!";
qosa_uint8_t hash_res[32] = {0};
// 一次性计算,调用完成后 hash_res 中即为32字节摘要结果
qcm_core_sha256(input_msg, sizeof(input_msg) - 1, hash_res);
}
大文件分段计算(流式计算):
#include "qcm_sha256.h"
#include "qosa_sys.h"
void app_sha_demo_long_file_sim() {
qcm_core_sha256_context_t ctx;
qosa_uint8_t final_res[32] = {0};
qosa_uint8_t file_chunk_buf[1024]; // 每次读取1024字节的数据缓冲区
// 1. 初始化并启动流式计算
qcm_sha256_init(&ctx);
qcm_sha256_starts(&ctx);
// 2. 循环读取文件并分段送入计算
while(/* 文件未读完,每次读取一段数据存入 file_chunk_buf */) {
qcm_sha256_update(&ctx, file_chunk_buf, 1024 /* 实际读取长度 */);
}
// 3. 结束计算并获取最终摘要
qcm_sha256_finish(&ctx, final_res);
// 4. 释放上下文
qcm_sha256_free(&ctx);
}