# RSA加解密 ***Copyright © Quectel Wireless Solutions Co., Ltd. 2026. All rights reserved.*** --- # 功能概述 本模块基于mbedTLS组件,通过通用公钥算法接口 *mbedtls_pk_** 提供RSA加解密能力。 RSA属于非对称密码算法,使用公钥加密、私钥解密。由于RSA计算复杂度较高,且可处理的明文长度受密钥长度和填充方式限制,通常只用于加密AES会话密钥、Token等少量敏感数据,不建议直接加密大块业务数据。 *mbedtls_pk_** 是mbedTLS提供的通用公钥算法接口,并非RSA专用接口。加载RSA密钥后,*mbedtls_pk_encrypt()* 和 *mbedtls_pk_decrypt()* 会调用底层RSA实现。 ## 主要应用场景 - 会话密钥保护:使用RSA公钥加密AES会话密钥。 - 设备敏感数据传输:加密长度较短的Token或认证信息。 - 混合加密:RSA保护对称密钥,AES-GCM/CCM保护业务数据。 RSA签名、证书验证和OTA验签属于签名验签能力,应使用 *mbedtls_pk_sign()* 和 *mbedtls_pk_verify()*,不属于本文档加解密接口的范围。 ## 常见问题 - RSA不适合加密大块数据,此类数据应使用AES等对称算法处理。 - 新设计应优先使用RSA-OAEP填充方式,禁止使用无填充的裸RSA。 - 建议使用不低于2048位的RSA密钥。 - RSA公钥可公开,私钥必须安全存储。 - 私钥不得硬编码、打印或以明文形式保存在普通Flash中。 - 公钥加密和私钥解密均需要安全随机数生成器。 - 解密失败后必须丢弃输出数据。 - 不应向外部暴露填充错误、密钥错误等具体解密失败原因。 - PEM格式密钥的输入长度必须包含末尾的 *\0*。 - 调用完成后必须使用 *mbedtls_pk_free()* 释放上下文。 ```{note} 当前版本的 *mbedtls_pk_encrypt()* 没有填充参数,具体填充方式由内部RSA上下文配置决定。如需明确指定OAEP及其Hash参数,应使用RSA专用OAEP接口、PSA Crypto接口。 ``` # RSA加解密API ## 头文件 *mbedtls/pk.h* *mbedtls/entropy.h* *mbedtls/ctr_drbg.h* ## 函数概览 | **函数** | **说明** | | --- | --- | | *mbedtls_pk_init()* | 初始化公钥算法上下文 | | *mbedtls_pk_parse_public_key()* | 解析PEM或DER格式公钥 | | *mbedtls_pk_parse_key()* | 解析PEM或DER格式私钥 | | *mbedtls_pk_can_do()* | 检查上下文是否支持指定算法 | | *mbedtls_pk_get_len()* | 获取密钥对应的输出长度 | | *mbedtls_pk_encrypt()* | 使用RSA公钥加密数据 | | *mbedtls_pk_decrypt()* | 使用RSA私钥解密数据 | | *mbedtls_pk_free()* | 释放公钥算法上下文 | ## 函数详解 ### mbedtls_pk_init - **功能描述** 初始化公钥算法上下文。调用密钥解析及RSA加解密接口前,必须先调用本函数。 - **函数原型** ```c void mbedtls_pk_init(mbedtls_pk_context *ctx); ``` - **参数说明** | **参数名** | **输入/输出** | **类型** | **说明** | | --- | --- | --- | --- | | *ctx* | 输出 | *mbedtls_pk_context ** | 待初始化的公钥算法上下文;不能为 *NULL*;详见 [*mbedtls_pk_context*](#mbedtlspkcontext) | - **返回值说明** 无 ### mbedtls_pk_parse_public_key - **功能描述** 解析PEM或DER格式的公钥,并将解析结果保存到 *mbedtls_pk_context* 中。 - **函数原型** ```c int mbedtls_pk_parse_public_key( mbedtls_pk_context *ctx, const unsigned char *key, size_t keylen); ``` - **参数说明** | **参数名** | **输入/输出** | **类型** | **说明** | | --- | --- | --- | --- | | *ctx* | 输入/输出 | *mbedtls_pk_context ** | 已初始化但尚未加载密钥的上下文;详见 [*mbedtls_pk_context*](#mbedtlspkcontext) | | *key* | 输入 | const unsigned char * | PEM或DER格式公钥 | | *keylen* | 输入 | size_t | 公钥数据长度;单位:字节;PEM格式时须包含末尾的 *\0* | - **返回值说明** *0*:函数执行成功 其他值(详见 [错误码](#错误码)):函数执行失败 ### mbedtls_pk_parse_key - **功能描述** 解析PEM或DER格式的私钥,并将解析结果保存到 *mbedtls_pk_context* 中。 - **函数原型** ```c int mbedtls_pk_parse_key( mbedtls_pk_context *ctx, const unsigned char *key, size_t keylen, const unsigned char *pwd, size_t pwdlen); ``` - **参数说明** | **参数名** | **输入/输出** | **类型** | **说明** | | --- | --- | --- | --- | | *ctx* | 输入/输出 | *mbedtls_pk_context ** | 已初始化但尚未加载密钥的上下文;详见 [*mbedtls_pk_context*](#mbedtlspkcontext) | | *key* | 输入 | const unsigned char * | PEM或DER格式私钥 | | *keylen* | 输入 | size_t | 私钥数据长度;单位:字节;PEM格式时须包含末尾的 *\0* | | *pwd* | 输入 | const unsigned char * | 私钥文件密码;无密码时传 *NULL* | | *pwdlen* | 输入 | size_t | 密码长度;单位:字节;无密码时传 *0* | - **返回值说明** *0*:函数执行成功 其他值(详见 [错误码](#错误码)):函数执行失败 ### mbedtls_pk_can_do - **功能描述** 检查当前上下文中加载的密钥是否支持指定的公钥算法。 - **函数原型** ```c int mbedtls_pk_can_do( const mbedtls_pk_context *ctx, mbedtls_pk_type_t type); ``` - **参数说明** | **参数名** | **输入/输出** | **类型** | **说明** | | --- | --- | --- | --- | | *ctx* | 输入 | *const mbedtls_pk_context ** | 已加载密钥的上下文;详见 [*mbedtls_pk_context*](#mbedtlspkcontext) | | *type* | 输入 | *mbedtls_pk_type_t* | 待检查的公钥算法类型;详见 [*mbedtls_pk_type_t*](#mbedtlspktype_t) | - **返回值说明** 非 *0*:支持指定算法 *0*:不支持指定算法 ### mbedtls_pk_get_len - **功能描述** 获取公钥算法输出数据的字节长度。对于RSA,该长度等于RSA模数长度。 - **函数原型** ```c size_t mbedtls_pk_get_len( const mbedtls_pk_context *ctx); ``` - **参数说明** | **参数名** | **输入/输出** | **类型** | **说明** | | --- | --- | --- | --- | | *ctx* | 输入 | *const mbedtls_pk_context ** | 已加载密钥的上下文;详见 [*mbedtls_pk_context*](#mbedtlspkcontext) | - **返回值说明** 大于 *0*:密钥对应的输出长度 *0*:上下文无效或尚未加载密钥 ### mbedtls_pk_encrypt - **功能描述** 使用上下文中的RSA公钥加密数据。加密操作需要随机数生成器,用于生成RSA填充所需的随机数据。 - **函数原型** ```c int mbedtls_pk_encrypt( mbedtls_pk_context *ctx, const unsigned char *input, size_t ilen, unsigned char *output, size_t *olen, size_t osize, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng); ``` - **参数说明** | **参数名** | **输入/输出** | **类型** | **说明** | | --- | --- | --- | --- | | *ctx* | 输入/输出 | *mbedtls_pk_context ** | 已加载RSA公钥的上下文;详见 [*mbedtls_pk_context*](#mbedtlspkcontext) | | *input* | 输入 | const unsigned char * | 待加密明文 | | *ilen* | 输入 | size_t | 明文长度;单位:字节;受密钥长度和填充方式限制 | | *output* | 输出 | unsigned char * | 密文输出缓冲区 | | *olen* | 输出 | size_t * | 实际密文长度;单位:字节 | | *osize* | 输入 | size_t | *output* 缓冲区容量;单位:字节 | | *f_rng* | 输入 | int (*)(void *, unsigned char *, size_t) | 安全随机数生成函数 | | *p_rng* | 输入 | void * | 随机数生成器上下文;与 *f_rng* 配套使用 | - **返回值说明** *0*:函数执行成功 其他值(详见 [错误码](#错误码)):函数执行失败 ### mbedtls_pk_decrypt - **功能描述** 使用上下文中的RSA私钥解密数据。随机数生成函数用于RSA私钥运算的盲化保护,可降低侧信道攻击风险。 - **函数原型** ```c int mbedtls_pk_decrypt( mbedtls_pk_context *ctx, const unsigned char *input, size_t ilen, unsigned char *output, size_t *olen, size_t osize, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng); ``` - **参数说明** | **参数名** | **输入/输出** | **类型** | **说明** | | --- | --- | --- | --- | | *ctx* | 输入/输出 | *mbedtls_pk_context ** | 已加载RSA私钥的上下文;详见 [*mbedtls_pk_context*](#mbedtlspkcontext) | | *input* | 输入 | const unsigned char * | RSA密文 | | *ilen* | 输入 | size_t | 密文长度;单位:字节 | | *output* | 输出 | unsigned char * | 明文输出缓冲区 | | *olen* | 输出 | size_t * | 实际明文长度;单位:字节 | | *osize* | 输入 | size_t | *output* 缓冲区容量;单位:字节 | | *f_rng* | 输入 | int (*)(void *, unsigned char *, size_t) | 安全随机数生成函数;通常传入 *mbedtls_ctr_drbg_random()* | | *p_rng* | 输入 | void * | 随机数生成器上下文;与 *f_rng* 配套使用 | - **返回值说明** *0*:函数执行成功 其他值(详见 [错误码](#错误码)):函数执行失败 ### mbedtls_pk_free - **功能描述** 释放公钥算法上下文内部申请的资源,并清理相关密钥材料。 - **函数原型** ```c void mbedtls_pk_free(mbedtls_pk_context *ctx); ``` - **参数说明** | **参数名** | **输入/输出** | **类型** | **说明** | | --- | --- | --- | --- | | *ctx* | 输入/输出 | *mbedtls_pk_context ** | 待释放的上下文;详见 [*mbedtls_pk_context*](#mbedtlspkcontext) | - **返回值说明** 无 ## 结构体定义 ### mbedtls_pk_context *mbedtls_pk_context* 是mbedTLS的通用公钥算法上下文,可保存RSA、ECDSA等不同类型的公钥或私钥,其结构体定义如下: ```c typedef struct mbedtls_pk_context { const mbedtls_pk_info_t *pk_info; void *pk_ctx; } mbedtls_pk_context; ``` | **参数** | **类型** | **说明** | | --- | --- | --- | | *pk_info* | const mbedtls_pk_info_t * | 当前密钥类型及对应的算法操作信息;例如RSA、RSA-PSS或EC密钥 | | *pk_ctx* | void * | 指向具体算法上下文;加载RSA密钥时,内部指向RSA上下文 | ## 枚举定义 ### mbedtls_pk_type_t 公钥算法类型枚举定义如下: ```c typedef enum { MBEDTLS_PK_NONE = 0, MBEDTLS_PK_RSA, MBEDTLS_PK_ECKEY, MBEDTLS_PK_ECKEY_DH, MBEDTLS_PK_ECDSA, MBEDTLS_PK_RSA_ALT, MBEDTLS_PK_RSASSA_PSS, MBEDTLS_PK_OPAQUE } mbedtls_pk_type_t; ``` | **成员** | **说明** | | --- | --- | | *MBEDTLS_PK_NONE* | 未加载密钥或未设置算法类型 | | *MBEDTLS_PK_RSA* | 普通RSA密钥;支持RSA加解密和签名验签 | | *MBEDTLS_PK_ECKEY* | 通用椭圆曲线密钥 | | *MBEDTLS_PK_ECKEY_DH* | 仅用于ECDH的椭圆曲线密钥 | | *MBEDTLS_PK_ECDSA* | ECDSA签名验签密钥 | | *MBEDTLS_PK_RSA_ALT* | 外部或硬件实现的替代RSA接口 | | *MBEDTLS_PK_RSASSA_PSS* | 仅用于RSA-PSS签名验签的RSA密钥 | | *MBEDTLS_PK_OPAQUE* | 由PSA或硬件安全模块管理的不透明密钥 | ## 错误码 | **错误码** | **值** | **说明** | | --- | --- | --- | | *MBEDTLS_ERR_PK_ALLOC_FAILED* | *-0x3F80* | 内存分配失败 | | *MBEDTLS_ERR_PK_TYPE_MISMATCH* | *-0x3F00* | 密钥类型与操作不匹配 | | *MBEDTLS_ERR_PK_BAD_INPUT_DATA* | *-0x3E80* | 输入参数或公钥算法上下文无效 | | *MBEDTLS_ERR_PK_KEY_INVALID_FORMAT* | *-0x3D00* | 公钥或私钥格式无效 | | *MBEDTLS_ERR_PK_UNKNOWN_PK_ALG* | *-0x3C80* | 无法识别或不支持密钥算法 | | *MBEDTLS_ERR_PK_PASSWORD_REQUIRED* | *-0x3C00* | 加密私钥需要密码 | | *MBEDTLS_ERR_PK_PASSWORD_MISMATCH* | *-0x3B80* | 私钥密码错误 | | *MBEDTLS_ERR_PK_INVALID_PUBKEY* | *-0x3B00* | 公钥数据无效 | | *MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE* | *-0x3980* | 当前固件未启用对应算法或功能 | | *MBEDTLS_ERR_RSA_BAD_INPUT_DATA* | *-0x4080* | RSA参数、数据或数据长度无效 | | *MBEDTLS_ERR_RSA_INVALID_PADDING* | *-0x4100* | RSA填充校验失败 | | *MBEDTLS_ERR_RSA_KEY_CHECK_FAILED* | *-0x4200* | RSA密钥有效性检查失败 | | *MBEDTLS_ERR_RSA_PUBLIC_FAILED* | *-0x4280* | RSA公钥运算失败 | | *MBEDTLS_ERR_RSA_PRIVATE_FAILED* | *-0x4300* | RSA私钥运算失败 | | *MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE* | *-0x4400* | 解密输出缓冲区不足 | | *MBEDTLS_ERR_RSA_RNG_FAILED* | *-0x4480* | 安全随机数生成失败 | | *MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION* | *-0x4500* | 当前实现不支持指定操作 | # 应用逻辑流程图 ```{image} images/image_KzuSbteMjo8mJzxfQ1Oc2SeAnah.webp :width: 1040px :height: 732px ``` # 示例代码 完整示例代码请查看:[https://github.com/UniRTOS/UniRTOS-Doc-Examples/blob/main/network/crypto/rsa_demo.c]( )