security_huks模块下hks_client.c代码评注(下)

本文深入剖析了Huks模块的hks_client.c文件,重点关注了AEAD加密、密钥派生和密钥许可协议的实现细节。AEAD加密通过hks_aead_encrypt函数实现,确保了数据的保密性和完整性。密钥派生函数hks_key_derivation和密钥许可协议函数hks_key_agreement分别用于派生密钥和许可密钥的生成。此外,介绍了hash运算相关函数集和服务类函数,如hks_register_file_callbacks和hks_register_get_hardware_udid_callback,这些函数提供了日志、文件回调和硬件UDID获取等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

hks_client.c总述(下)

本篇解上篇代码评注展开,上篇详见:security_huks模块下hks_client.c代码评注(上)

代码关键部分模块框架

hks_client.c
├── include
│   └── "hks_client.h"
│   └── "hks_access.h"
│   └── "soft_service/hks_service.h"
│   └── "hks_types.h"
│   └── "common/hks_common.h"                           
├── functions                        
│   └── hks_client.h
│   		└── hks_get_sdk_version                
│   └── hks_access.c
│   		└── hks_access_generate_key
│   		└── hks_access_generate_key_ex
│   		└── hks_access_import_key
│   		└── hks_access_export_key
│   		└── hks_access_delete_key
│   		└── hks_access_get_key_param
│   		└── hks_access_is_key_exist
│   		└── hks_access_sign
│   		└── hks_access_verify
│   		└── hks_access_aead_encrypt
│   		└── hks_access_aead_decrypt
│   		└── hks_access_key_derivation
│   		└── hks_access_key_agreement
│   		└── hks_access_get_random
│   		└── hks_access_hmac
│   		└── hks_access_hash
│   		└── hks_access_bn_exp_mod
│   		└── hks_access_get_pub_key_alias_list
│   		└── hks_access_init
│   		└── hks_access_destroy
│   		└── hks_access_refresh_key_info                  
│   └── hks_service.c
│   		└── hks_service_register_file_callbacks
│   		└── hks_service_register_get_hardware_udid_callback
│   └── hks_log_utils.c
│   		└── hks_register_log

本篇主要讲述hks_access_aead_encrypt函数之后的部分内容。

各模块详解

hks的aead加密

其中函数hks_aead_encrypt调用了函数hks_aead_encrypt_ree,且函数hks_aead_encrypt_ree在检查过密钥、密钥参数、明文、带标记的密文等相关信息后是通过调用hks_access_aead_encrypt函数实现的。
hks的aead解密部分的代码理解同hks的aead加密,代码部分省略。

//hks的aead加密
static int32_t hks_aead_encrypt_ree(const struct hks_blob *key,
    const struct hks_key_param *key_param,          //密匙参数
    const struct hks_crypt_param *crypt_param,      //加密参数
    const struct hks_blob *plain_text,              //明文
    struct hks_blob *cipher_text_with_tag)          //带标记的密文
{
    hks_if_true_return_error(((key_param->key_type != HKS_KEY_TYPE_AES) ||  //检查密匙参数的类型是否为AES加密类型
        (key_param->key_mode != HKS_ALG_GCM) ||                             //检查密匙参数的模式是否为GCM加密模式
        (key_param->key_pad != HKS_PADDING_NONE) ||                         //检查密匙是否存在padding补位
        ((key_param->key_usage & HKS_KEY_USAGE_ENCRYPT) == 0)), HKS_ERROR_NOT_SUPPORTED);//检查密匙应用是否加密

    //检查密匙的长度有没有超过最大长度
    hks_if_true_return_error(((key_param->key_len != HKS_MAX_KEY_LEN_128) &&
        (key_param->key_len != HKS_MAX_KEY_LEN_192) &&
        (key_param->key_len != HKS_MAX_KEY_LEN_256)), HKS_ERROR_NOT_SUPPORTED);

    //检查密匙的类型与大小是否满足HKS_ERROR_INVALID_KEY_INFO
    hks_if_true_return_error(((key->type != HKS_BLOB_TYPE_KEY) || (key->data == NULL) ||
        (key->size != (key_param->key_len / HKS_BITS_PER_BYTES))), HKS_ERROR_INVALID_KEY_INFO);

    //检查加密参数信息的内容、大小以及明文的内容和大小是否满足HKS_ERROR_INVALID_ARGUMENT
    hks_if_true_return_error(((crypt_param->nonce.data == NULL) ||
        (crypt_param->nonce.size < HKS_AES_GCM_MIN_IV_LENGTH) ||
        (crypt_param->aad.data == NULL) ||
        (crypt_param->aad.size == 0) ||
        (plain_text->data == NULL) || (plain_text->size == 0)), HKS_ERROR_INVALID_ARGUMENT);

    //检查带标记的密文信息内容和大小是否满足HKS_ERROR_INVALID_ARGUMENT
    hks_if_true_return_error(((cipher_text_with_tag == NULL) ||
        (cipher_text_with_tag->data == NULL) ||
        (cipher_text_with_tag->size < (plain_text->size + HKS_SALT_MAX_SIZE))),
        HKS_ERROR_INVALID_ARGUMENT);

    //如果上述条件都成立则执行hks_access_aead_encrypt函数
    return hks_access_aead_encrypt(key, key_param, crypt_param, plain_text, cipher_text_with_tag);
}

//AEAD算法下的加密函数,先对传入参数进行检查,再调用了hks_aead_encrypt_ree,*****相当于把hks_aead_encrypt_ree做了一个封装*****
HKS_DLL_API_PUBLIC int32_t hks_aead_encrypt(const struct hks_blob *key,
    const struct hks_key_param *key_param,
    const struct hks_crypt_param *crypt_param,
    const struct hks_blob *plain_text,
    struct hks_blob *cipher_text_with_tag)
{
    //检查密匙、密匙参数、加密参数、明文、带标记的密文信息是否为空
    hks_if_true_return_error(((key == NULL) || (key_param == NULL) ||
        (crypt_param == NULL || (plain_text == NULL) ||
        (cipher_text_with_tag == NULL))), HKS_ERROR_NULL_POINTER);
    return hks_aead_encrypt_ree(key, key_param, crypt_param, plain_text, cipher_text_with_tag);
}

hks的密钥派生和密钥许可协议

hks的密钥派生函数:hks_key_derivation需要传入参数的有:
derived_key 派生密钥
hks_key_param hks密钥参数
kdf_key kdf密钥

hks密钥许可协议函数:hks_key_agreement需要传入参数的有:
agreed_key 许可密钥
private_key_param 私有密钥参数
agreement_alg alg协议
private_key 私有密钥
peer_public_key 对等公有密钥

//hks密匙派生
HKS_DLL_API_PUBLIC int32_t hks_key_derivation(struct hks_blob *derived_key,
    const struct hks_key_param *key_param, const struct hks_blob *kdf_key,
    const struct hks_blob *salt, const struct hks_blob *label)
{
    hks_if_true_return_error(((derived_key == NULL) ||
        (key_param == NULL) || (kdf_key == NULL) ||
        (salt == NULL) || (label == NULL)),
        HKS_ERROR_NULL_POINTER);
    //执行获取密匙派生信息对应的函数
    return hks_access_key_derivation(derived_key, kdf_key, salt, label,
        key_param);
}

//hks密匙许可协议
//需要传入许可密匙:agreed_key、私有密匙参数:private_key_param、alg协议:agreement_alg、私有密匙:private_key、对等公有密匙:peer_public_key
HKS_DLL_API_PUBLIC int32_t hks_key_agreement(struct hks_blob *agreed_key,
    const struct hks_key_param *private_key_param,
    const uint32_t agreement_alg, const struct hks_blob *private_key,
    const struct hks_blob *peer_public_key)
{
#ifdef _CUT_AUTHENTICATE_
    return HKS_ERROR_NOT_SUPPORTED;
#else
    //检查传入参数是否为空
    hks_if_true_return_error(((agreed_key == NULL) ||
        (private_key_param == NULL) || (private_key == NULL) ||
        (peer_public_key == NULL)), HKS_ERROR_NULL_POINTER);

    if ((agreed_key == NULL) || (agreed_key->data == NULL))
        return HKS_ERROR_NULL_POINTER;

    //检查许可密匙大小是否符合HKS_KEY_BYTES_CURVE25519
    if (agreed_key->size < HKS_KEY_BYTES_CURVE25519)
        return HKS_ERROR_INVALID_KEY_INFO;

    //检查密匙是否使用了特定加密方法HKS_KEY_TYPE_ECC_KEYPAIR_CURVE25519、密匙应用与模式是否合规
    if ((private_key_param->key_type !=
        HKS_KEY_TYPE_ECC_KEYPAIR_CURVE25519) ||
        (private_key_param->key_usage != HKS_KEY_USAGE_DERIVE) ||
        (private_key_param->key_mode != hks_alg_ecdh(HKS_ALG_ECDH_RAW)) ||
        (agreement_alg != hks_alg_ecdh(HKS_ALG_ECDH_RAW)))
        return HKS_ERROR_NOT_SUPPORTED;

    //检查私有密匙和对等公有密匙的数据和大小是否合规
    if ((private_key->data == NULL) ||
        (private_key->size != HKS_KEY_BYTES_CURVE25519))
        return HKS_ERROR_INVALID_PRIVATE_KEY;

    if ((peer_public_key->data == NULL) ||
        (peer_public_key->size != HKS_KEY_BYTES_CURVE25519))
        return HKS_ERROR_INVALID_PUBLIC_KEY;
    //执行获取密匙协议相对应的函数
    return hks_access_key_agreement(agreed_key,
        private_key_param, private_key, peer_public_key, agreement_alg);
#endif
}

hash运算相关函数集

该部分包括以下函数:
hks_generate_random
hks_hmac
hks_hash
hks_if_true_return_error
hks_bn_exp_mod
具体执行功能都是调用了hks_access.c中的对应功能函数。


//hks生成随机数
HKS_DLL_API_PUBLIC int32_t hks_generate_random(struct hks_blob *random)
{
    hks_if_true_return_error(((random == NULL) || (random->data == NULL)),
        HKS_ERROR_NULL_POINTER);
    hks_if_true_return_error((random->size > HKS_RANDOM_MAX_LEN),
        HKS_ERROR_INVALID_ARGUMENT);
    //调用hks_access_get_random函数
    return hks_access_get_random(random);
}

//hks获取哈希运算验证码
HKS_DLL_API_PUBLIC int32_t hks_hmac(const struct hks_blob *key,
    const uint32_t alg, const struct hks_blob *src_data,
    struct hks_blob *output)
{
    hks_if_true_return_error(((key == NULL) || (src_data == NULL) ||
        (output == NULL)), HKS_ERROR_NULL_POINTER);
    //调用hks_access_hmac函数
    return hks_access_hmac(key, alg, src_data, output);
}

//hks哈希算法
HKS_DLL_API_PUBLIC int32_t hks_hash(const uint32_t alg,
    const struct hks_blob *src_data, struct hks_blob *hash)
{
#ifdef _CUT_AUTHENTICATE_
    return HKS_ERROR_NOT_SUPPORTED;
#else
    hks_if_true_return_error(((src_data == NULL) || (hash == NULL)),
        HKS_ERROR_NULL_POINTER);
    //调用hks_access_hash函数
    return hks_access_hash(alg, src_data, hash);
#endif
}

//hks大整数模幂运算
HKS_DLL_API_PUBLIC int32_t hks_bn_exp_mod(struct hks_blob *x,
    const struct hks_blob *a, const struct hks_blob *e,
    const struct hks_blob *n)
{
    hks_if_true_return_error(((x == NULL) || (a == NULL) || (e == NULL) ||
        (n == NULL)), HKS_ERROR_NULL_POINTER);
    //调用hks_access_bn_exp_mod函数
    return hks_access_bn_exp_mod(x, a, e, n);
}

服务类函数集

该部分包括以下函数:
hks_register_file_callbacks
hks_register_get_hardware_udid_callback
hks_register_log_interface
能够实现注册文件回调、注册日志界面等功能

//hks注册文件回调
HKS_DLL_API_PUBLIC int32_t hks_register_file_callbacks(
    struct hks_file_callbacks *callbacks)
{
#ifdef _CUT_AUTHENTICATE_
    return HKS_SUCCESS;
#else
    if (callbacks == NULL)
        return HKS_ERROR_NULL_POINTER;
    //调用hks_service_register_file_callbacks函数执行注册文件回调功能
    return hks_service_register_file_callbacks(callbacks);
#endif
}

//hks注册获取硬件udid回调,注:UDID(Unique Device Identifier)
HKS_DLL_API_PUBLIC int32_t hks_register_get_hardware_udid_callback(
    hks_get_hardware_udid_callback callback)
{
#ifdef _CUT_AUTHENTICATE_
    return HKS_SUCCESS;
#else
    //调用hks_service_register_get_hardware_udid_callback函数,HKS服务寄存器获取硬件udid回调
    return hks_service_register_get_hardware_udid_callback(callback);
#endif
}

//hks注册日志界面,传入日志组件参数信息
HKS_DLL_API_PUBLIC int32_t hks_register_log_interface(
    const struct hks_log_f_group *log)
{
    if (log == NULL)
        return HKS_ERROR_NULL_POINTER;
    //执行hks_register_log,将日志组件写入g_log_func中
    hks_register_log(log);
    return HKS_STATUS_OK;
}

其他函数

该部分包括以下函数:
hks_get_pub_key_alias_list
hks_init
hks_destroy
hks_refresh_key_info
具体函数内部调用的执行功能函数见hks_access.c。

//hks获取公有密钥别名列表
HKS_DLL_API_PUBLIC int32_t hks_get_pub_key_alias_list(
    struct hks_blob *key_alias_list, uint32_t *list_count)
{
#ifdef _CUT_AUTHENTICATE_
    return HKS_ERROR_NOT_SUPPORTED;
#else
    if ((key_alias_list == NULL) || (list_count == NULL))
        return HKS_ERROR_NULL_POINTER;

    //执行hks_access_get_pub_key_alias_list函数
    return hks_access_get_pub_key_alias_list(key_alias_list, list_count);
#endif
}

//hks初始化
HKS_DLL_API_PUBLIC int32_t hks_init(void)
{
#ifdef _CUT_AUTHENTICATE_
    log_debug("call hks init success.");
    return HKS_SUCCESS;
#else
    //执行hks权限初始化操作
    return hks_access_init();
#endif
}

//hks销毁(删除)
HKS_DLL_API_PUBLIC void hks_destroy(void)
{
#ifdef _CUT_AUTHENTICATE_
    return;
#else
    //执行函数hks_access_destroy
    hks_access_destroy();
#endif
}

//hks更新密匙信息
HKS_DLL_API_PUBLIC int32_t hks_refresh_key_info(void)
{
#ifdef _CUT_AUTHENTICATE_
    return HKS_SUCCESS;
#else
    //执行函数hks_access_refresh_key_info
    return hks_access_refresh_key_info();
#endif
}

知识提点

AEAD加密

  1. 定义
    Authenticated encryption with associated data (AEAD) are encryption schemes which provide both confidentiality and integrity for their ciphertext. They also support providing integrity for associated data which is not encrypted.

    带关联数据的身份验证加密(AEAD)是为其密文提供保密性和完整性的加密方案。它们还支持为未加密的相关数据提供完整性。

  2. 进一步解释
    Authenticated Encryption with Associated Data (AEAD) 是一种同时具备保密性,完整性和可认证性的加密形式。

    AEAD 产生的原因很简单,单纯的对称加密算法,其解密步骤是无法确认密钥是否正确的。也就是说,加密后的数据可以用任何密钥执行解密运算,得到一组疑似原始数据,而不知道密钥是否是正确的,也不知道解密出来的原始数据是否正确。

    因此,需要在单纯的加密算法之上,加上一层验证手段,来确认解密步骤是否正确。

  3. 实现步骤
    通过密钥key对消息加密,通过增加随机数来保证隐私;
    计算一个认证标签,通过该认证标签可保证一条消息中加密和未加密的部分均未被篡改。

  4. AEAD加密算法分类:
    在这里插入图片描述
    其中GCM为AEAD加密算法中的典型,GCM算法的流程图如下:
    在这里插入图片描述
    其中依次用到的GHASH和GCTR的流程图如下:
    在这里插入图片描述

服务类调用原函数参考

  1. hks_service_register_file_callbacks

    int32_t hks_service_register_file_callbacks(
        const struct hks_file_callbacks *callbacks)
    {
        if (callbacks == NULL)
            return HKS_ERROR_NULL_POINTER;
    
        return hks_file_register_callbacks(callbacks);
    }
    
  2. hks_service_register_get_hardware_udid_callback

    int32_t hks_service_register_get_hardware_udid_callback(
        hks_get_hardware_udid_callback callback)
    {
        return hks_reg_get_hardware_udid_callback(callback);
    }
    
  3. hks_register_log

    void hks_register_log(const struct hks_log_f_group *log)
    {
        if (log == NULL)
            return;
    
        if (log->log_info != NULL)
            g_log_func.log_info = log->log_info;
    
        if (log->log_warn != NULL)
            g_log_func.log_warn = log->log_warn;
    
        if (log->log_error != NULL)
            g_log_func.log_error = log->log_error;
    
        if (log->log_debug != NULL)
            g_log_func.log_debug = log->log_debug;
    }
    

本篇结束,感谢您的阅读与点赞!

<think>嗯,用户遇到了找不到模块@ohos.security.hash的问题,这需要我帮忙解决。首先,我得回想一下鸿蒙开发的模块结构。根据用户提供的引用资料,特别是引用[2]和引用[3],鸿蒙的安全模块主要是通过@ohos.security.huks来管理密钥和加密操作的。可能用户提到的hash模块其实是集成在HUKS中的,而不是单独的模块。 接下来,我需要确认是否存在@ohos.security.hash这个官方模块。查阅鸿蒙的官方文档,发现确实没有这个模块,而是哈希功能被包含在HUKS里。用户可能在文档或示例中看到过类似名称,导致混淆了模块名称。 然后,用户可能导入了错误的模块名,应该改用@ohos.security.huks。需要指导用户检查代码中的import语句,替换为正确的模块。同时,确保系统能力SystemCapability.Security.Huks已正确配置,这在引用[2]中提到过。 另外,用户可能需要使用HuksParam来指定摘要算法,比如SHA256。需要提供示例代码,展示如何正确调用HUKS的接口进行哈希操作,并处理可能的错误。 最后,提醒用户检查SDK版本和依赖,确保一切更新到最新,避免兼容性问题。如果问题依然存在,建议用户查阅官方资源或社区寻求帮助。总结下来,核心问题在于模块名称的错误,替换成HUKS并正确使用其API应该能解决问题。</think>### 如何解决 `@ohos.security.hash` 模块未找到的问题? #### 问题分析 根据你提供的引用信息,鸿蒙系统的安全模块中并未直接提供名为 `@ohos.security.hash` 的独立模块。鸿蒙的安全功能主要通过 `@ohos.security.huks`(通用密钥库系统)实现,包括哈希算法、加密解密等操作[^2][^3]。 #### 解决步骤 1. **确认模块名称的正确性** - 官方文档中,哈希算法功能通过 `@ohos.security.huks` 提供,而非单独的 `@ohos.security.hash`。需检查代码中是否错误引用了模块名称。 2. **使用 `@ohos.security.huks` 实现哈希功能** - 哈希算法(如 SHA1、SHA256)在 `huks` 模块中被定义为摘要算法。例如,`HUKS_DIGEST_SHA256` 表示使用 SHA256 算法。 - **示例代码**: ```typescript import huks from '@ohos.security.huks'; // 定义哈希参数 let options = { properties: [ { tag: huks.HuksTag.HUKS_TAG_ALGORITHM, value: huks.HuksKeyAlg.HUKS_ALG_RSA }, { tag: huks.HuksTag.HUKS_TAG_DIGEST, value: huks.HuksKeyDigest.HUKS_DIGEST_SHA256 } ] }; // 调用哈希功能 async function hashData(data: Uint8Array) { try { const hashResult = await huks.initSession('default_key', options); console.info('Hash result:', hashResult); } catch (error) { console.error('Hash failed:', error); } } ``` 3. **检查系统能力配置** - 在 `module.json5` 文件中,确保已声明系统能力 `SystemCapability.Security.Huks`[^2]: ```json { "module": { "requestPermissions": [ { "name": "SystemCapability.Security.Huks" } ] } } ``` 4. **确认 SDK 版本与依赖** - 若开发环境版本过旧,可能导致模块缺失。建议更新 DevEco Studio 至最新版本,并同步鸿蒙 SDK。 #### 相关问题 1. **鸿蒙中如何实现数据加密与解密?** - 通过 `@ohos.security.huks` 提供密钥管理和加密接口,支持 AES、RSA 等算法。 2. **如何选择适合的摘要算法?** - 根据安全需求选择,例如 SHA256 平衡性能与安全性,SHA512 适用于更高安全场景[^1]。 3. **鸿蒙安全模块代码结构如何分析?** - 可参考 `security_huks` 的框架层次,其核心逻辑在 `.c` 和 `.cpp` 文件中实现,结合单元测试验证功能。 #### 总结 问题根源在于模块名称引用错误,正确使用 `@ohos.security.huks` 并配置对应参数即可实现哈希功能。若仍存在问题,建议查阅官方文档或社区资源进一步验证。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值