ECDSA签名算法¶
Copyright © Quectel Wireless Solutions Co., Ltd. 2026. All rights reserved.
功能概述¶
ECDSA是一种基于椭圆曲线的数字签名算法,用于验证数据来源是否可信、内容是否被篡改。当前系统基于Mbed TLS/PSA Crypto提供ECDSA能力,可支持签名生成、签名合法性校验,以及与ECC密钥、SHA摘要算法配合完成安全认证流程。
在实际使用中,ECDSA通常不作为独立业务功能提供,而是作为TLS、证书校验、设备认证、eSIM认证等安全链路中的底层密码能力使用。
常见应用场景¶
TLS安全连接认证:在HTTPS、MQTT over TLS、WebSocket over TLS等安全通信场景中,ECDSA可用于服务器证书或客户端证书的身份认证。设备在建立TLS连接时,会校验证书链中的ECDSA签名,确认通信对端证书是否可信,从而防止连接到伪造服务器或非法设备。
X.509证书链校验:ECDSA可用于验证X.509证书中的签名是否合法。例如CA证书对下级证书的签名、业务证书公钥算法的匹配性检查、证书链完整性验证等环节,都可能涉及ECDSA校验。若证书使用的公钥算法、曲线或签名格式不符合要求,系统会判定为证书校验异常。
eSIM远程认证流程:在eSIM相关业务中,ECDSA可用于校验远程服务端或认证实体的证书与签名,例如CERT.DPAuth.ECDSA相关认证流程。通过ECDSA校验,可以确认SM-DP+等远程实体的身份可信,保障profile下载、安装、认证过程的安全性。
数据完整性和来源校验:对于固件包、配置文件、授权数据、业务令牌等关键数据,也可以使用ECDSA进行签名校验。设备侧通过公钥验证签名,确认数据未被篡改且来源可信,适用于安全升级、授权校验、关键配置下发等场景。
常见问题¶
使用ECDSA时,需要确保签名格式、公钥、曲线参数和摘要算法与签名生成端保持一致。常见问题包括签名格式RAW/DER不匹配、公钥或证书算法不支持、曲线参数不符合系统配置、原始数据或摘要被修改等。
ECDSA验签依赖正确的证书链和可信根证书配置。
在多线程场景下,不建议多个线程同时复用同一个ECDSA上下文。
实际业务中建议优先使用系统已配置支持的曲线和摘要算法,避免引入未验证的自定义曲线或非标准签名格式。
ECDSA签名流程¶
ECDSA的典型流程分为密钥准备、签名生成、签名验证三个阶段。
密钥准备流程¶
首先选择一条椭圆曲线,如 secp256r1、secp384r1。
然后生成一对ECC密钥:
私钥:由签名方保存,用来生成签名,不得泄露。
公钥:分发给验证方,用于校验签名是否合法。
即:私钥负责签名,公钥负责验签。
签名生成流程¶
签名方获取原始数据后,通常不直接对完整数据签名,而是先计算摘要。
流程如下:
对原始数据计算Hash,如SHA-256、SHA-384。
使用ECC私钥对Hash结果进行ECDSA签名。
输出签名结果,通常包含两个值:r、s。
根据协议要求,将签名编码成RAW或DER格式。
将原始数据或摘要、签名值、证书或公钥一起发送给验证方。
签名验证流程¶
验证方收到数据和签名后,会使用签名方的公钥进行校验。
流程如下:
获取原始数据、签名值和签名方公钥。
对原始数据使用相同Hash算法计算摘要。
检查签名格式是否合法,包括RAW/DER编码、长度以及r、s值是否有效。
检查公钥和曲线参数是否符合要求。
使用ECDSA验签算法校验签名是否匹配。
验签通过,表明数据未被篡改且来源可信;验签失败,表明数据、签名、公钥或算法参数不匹配。
ECDSA签名算法API¶
头文件¶
psa/crypto.h
函数概览¶
函数 |
说明 |
|---|---|
|
初始化PSA Crypto组件 |
|
设置密钥类型及椭圆曲线族 |
|
设置密钥位数 |
|
设置密钥允许的用途 |
|
设置密钥允许使用的算法 |
|
生成ECDSA密钥对 |
|
导入已有私钥或公钥 |
|
导出密钥对中的公钥 |
|
计算消息哈希 |
|
对原始消息进行签名 |
|
验证原始消息签名 |
|
对已计算的哈希值签名 |
|
验证哈希值签名 |
|
销毁密钥 |
|
重置密钥属性结构体 |
函数详解¶
psa_crypto_init()¶
功能描述
初始化PSA Crypto模块。调用其他PSA Crypto接口前,必须先调用本函数。函数原型
psa_status_t psa_crypto_init(void);
参数说明
无返回值说明
PSA_SUCCESS:函数执行成功
其他值(详见 psa_status_t):函数执行失败
psa_set_key_type()¶
功能描述
设置密钥属性中的密钥类型。函数原型
void psa_set_key_type(psa_key_attributes_t *attributes,
psa_key_type_t type);
参数说明
参数名 |
输入/输出 |
类型 |
说明 |
|---|---|---|---|
attributes |
输入/输出 |
psa_key_attributes_t* |
密钥属性对象;详见 psa_key_attributes_t |
type |
输入 |
psa_key_type_t |
密钥类型;ECDSA常用 PSA_KEY_TYPE_ECC_KEY_PAIR() 或 PSA_KEY_TYPE_ECC_PUBLIC_KEY();详见 psa_key_type_t |
返回值说明
无
psa_set_key_bits()¶
功能描述
设置密钥属性中的密钥位宽。函数原型
void psa_set_key_bits(psa_key_attributes_t *attributes,
size_t bits);
参数说明
参数名 |
输入/输出 |
类型 |
说明 |
|---|---|---|---|
attributes |
输入/输出 |
psa_key_attributes_t* |
密钥属性对象;详见 psa_key_attributes_t |
bits |
输入 |
size_t |
密钥位宽;常用取值:256、384、521;单位:位 |
返回值说明
无
psa_set_key_usage_flags()¶
功能描述
设置密钥允许执行的用途。函数原型
void psa_set_key_usage_flags(psa_key_attributes_t *attributes,
psa_key_usage_t usage_flags);
参数说明
参数名 |
输入/输出 |
类型 |
说明 |
|---|---|---|---|
attributes |
输入/输出 |
psa_key_attributes_t* |
密钥属性对象;详见 psa_key_attributes_t |
usage_flags |
输入 |
psa_key_usage_t |
密钥用途;常用 PSA_KEY_USAGE_SIGN_HASH、PSA_KEY_USAGE_VERIFY_HASH;详见 psa_key_usage_t |
返回值说明
无
psa_set_key_algorithm()¶
功能描述
设置密钥允许使用的算法。函数原型
void psa_set_key_algorithm(psa_key_attributes_t *attributes,
psa_algorithm_t alg);
参数说明
参数名 |
输入/输出 |
类型 |
说明 |
|---|---|---|---|
attributes |
输入/输出 |
psa_key_attributes_t* |
密钥属性对象;详见 psa_key_attributes_t |
alg |
输入 |
psa_algorithm_t |
密钥允许使用的算法;常用 PSA_ALG_ECDSA(PSA_ALG_SHA_256);详见 psa_algorithm_t |
返回值说明
无
psa_generate_key()¶
功能描述
根据密钥属性生成密钥。函数原型
psa_status_t psa_generate_key(const psa_key_attributes_t *attributes,
mbedtls_svc_key_id_t *key);
参数说明
参数名 |
输入/输出 |
类型 |
说明 |
|---|---|---|---|
attributes |
输入 |
const psa_key_attributes_t* |
密钥属性对象;详见 psa_key_attributes_t |
key |
输出 |
mbedtls_svc_key_id_t * |
生成后的密钥标识 |
返回值说明
PSA_SUCCESS:函数执行成功
其他值(详见 psa_status_t):函数执行失败
psa_import_key()¶
功能描述
根据密钥属性导入外部密钥。函数原型
psa_status_t psa_import_key(const psa_key_attributes_t *attributes,
const uint8_t *data,
size_t data_length,
mbedtls_svc_key_id_t *key);
参数说明
参数名 |
输入/输出 |
类型 |
说明 |
|---|---|---|---|
attributes |
输入 |
const psa_key_attributes_t* |
密钥属性对象;详见 psa_key_attributes_t |
data |
输入 |
const uint8_t * |
待导入的密钥数据 |
data_length |
输入 |
size_t |
密钥数据长度;单位:字节 |
key |
输出 |
mbedtls_svc_key_id_t * |
导入后的密钥标识 |
返回值说明
PSA_SUCCESS:函数执行成功
其他值(详见 psa_status_t):函数执行失败
psa_hash_compute()¶
功能描述
计算输入数据的Hash摘要。函数原型
psa_status_t psa_hash_compute(psa_algorithm_t alg,
const uint8_t *input,
size_t input_length,
uint8_t *hash,
size_t hash_size,
size_t *hash_length);
参数说明
参数名 |
输入/输出 |
类型 |
说明 |
|---|---|---|---|
alg |
输入 |
psa_algorithm_t |
Hash算法;常用 PSA_ALG_SHA_256;详见 psa_algorithm_t |
input |
输入 |
const uint8_t * |
待计算摘要的原始数据 |
input_length |
输入 |
size_t |
原始数据长度;单位:字节 |
hash |
输出 |
uint8_t * |
摘要输出缓冲区 |
hash_size |
输入 |
size_t |
摘要输出缓冲区大小;单位:字节 |
hash_length |
输出 |
size_t * |
实际输出的摘要长度;单位:字节 |
返回值说明
PSA_SUCCESS:函数执行成功
其他值(详见 psa_status_t):函数执行失败
psa_sign_hash()¶
功能描述
对已计算完成的摘要数据生成ECDSA签名。函数原型
psa_status_t psa_sign_hash(mbedtls_svc_key_id_t key,
psa_algorithm_t alg,
const uint8_t *hash,
size_t hash_length,
uint8_t *signature,
size_t signature_size,
size_t *signature_length);
参数说明
参数名 |
输入/输出 |
类型 |
说明 |
|---|---|---|---|
key |
输入 |
mbedtls_svc_key_id_t |
签名使用的ECC私钥标识 |
alg |
输入 |
psa_algorithm_t |
签名算法;常用 PSA_ALG_ECDSA(PSA_ALG_SHA_256);详见 psa_algorithm_t |
hash |
输入 |
const uint8_t * |
待签名的摘要数据 |
hash_length |
输入 |
size_t |
摘要数据长度;单位:字节 |
signature |
输出 |
uint8_t * |
签名结果输出缓冲区 |
signature_size |
输入 |
size_t |
签名结果缓冲区大小;单位:字节 |
signature_length |
输出 |
size_t * |
实际生成的签名长度;单位:字节 |
返回值说明
PSA_SUCCESS:函数执行成功
其他值(详见 psa_status_t):函数执行失败
psa_verify_hash()¶
功能描述
校验已计算完成的摘要数据与ECDSA签名是否匹配。函数原型
psa_status_t psa_verify_hash(mbedtls_svc_key_id_t key,
psa_algorithm_t alg,
const uint8_t *hash,
size_t hash_length,
const uint8_t *signature,
size_t signature_length);
参数说明
参数名 |
输入/输出 |
类型 |
说明 |
|---|---|---|---|
key |
输入 |
mbedtls_svc_key_id_t |
验签使用的ECC公钥或密钥对标识 |
alg |
输入 |
psa_algorithm_t |
验签算法;常用 PSA_ALG_ECDSA(PSA_ALG_SHA_256);详见 psa_algorithm_t |
hash |
输入 |
const uint8_t * |
待验签的摘要数据 |
hash_length |
输入 |
size_t |
摘要数据长度;单位:字节 |
signature |
输入 |
const uint8_t * |
待校验的ECDSA签名数据 |
signature_length |
输入 |
size_t |
签名数据长度;单位:字节 |
返回值说明
PSA_SUCCESS:函数执行成功
其他值(详见 psa_status_t):函数执行失败
psa_sign_message()¶
功能描述
对原始消息数据生成ECDSA签名。函数原型
psa_status_t psa_sign_message(mbedtls_svc_key_id_t key,
psa_algorithm_t alg,
const uint8_t *input,
size_t input_length,
uint8_t *signature,
size_t signature_size,
size_t *signature_length);
参数说明
参数名 |
输入/输出 |
类型 |
说明 |
|---|---|---|---|
key |
输入 |
mbedtls_svc_key_id_t |
签名使用的ECC私钥标识 |
alg |
输入 |
psa_algorithm_t |
签名算法;常用 PSA_ALG_ECDSA(PSA_ALG_SHA_256);详见 psa_algorithm_t |
input |
输入 |
const uint8_t * |
待签名的原始消息数据 |
input_length |
输入 |
size_t |
原始消息数据长度;单位:字节 |
signature |
输出 |
uint8_t * |
签名结果输出缓冲区 |
signature_size |
输入 |
size_t |
签名结果缓冲区大小;单位:字节 |
signature_length |
输出 |
size_t * |
实际生成的签名长度;单位:字节 |
返回值说明
PSA_SUCCESS:函数执行成功
其他值(详见 psa_status_t):函数执行失败
psa_verify_message()¶
功能描述
校验原始消息数据与ECDSA签名是否匹配。函数原型
psa_status_t psa_verify_message(mbedtls_svc_key_id_t key,
psa_algorithm_t alg,
const uint8_t *input,
size_t input_length,
const uint8_t *signature,
size_t signature_length);
参数说明
参数名 |
输入/输出 |
类型 |
说明 |
|---|---|---|---|
key |
输入 |
mbedtls_svc_key_id_t |
验签使用的ECC公钥或密钥对标识 |
alg |
输入 |
psa_algorithm_t |
验签算法;常用 PSA_ALG_ECDSA(PSA_ALG_SHA_256);详见 psa_algorithm_t |
input |
输入 |
const uint8_t * |
待验签的原始消息数据 |
input_length |
输入 |
size_t |
原始消息数据长度;单位:字节 |
signature |
输入 |
const uint8_t * |
待校验的ECDSA签名数据 |
signature_length |
输入 |
size_t |
签名数据长度;单位:字节 |
返回值说明
PSA_SUCCESS:函数执行成功
其他值(详见 psa_status_t):函数执行失败
psa_destroy_key()¶
功能描述
销毁指定密钥并释放相关资源。函数原型
psa_status_t psa_destroy_key(mbedtls_svc_key_id_t key);
参数说明
参数名 |
输入/输出 |
类型 |
说明 |
|---|---|---|---|
key |
输入 |
mbedtls_svc_key_id_t |
需要销毁的密钥标识 |
返回值说明
PSA_SUCCESS:函数执行成功
其他值(详见 psa_status_t):函数执行失败
psa_reset_key_attributes()¶
功能描述
重置密钥属性对象。函数原型
void psa_reset_key_attributes(psa_key_attributes_t *attributes);
参数说明
参数名 |
输入/输出 |
类型 |
说明 |
|---|---|---|---|
attributes |
输出 |
psa_key_attributes_t* |
密钥属性对象;详见 psa_key_attributes_t |
返回值说明
无
结构体定义¶
psa_key_attributes_t¶
PSA密钥属性结构体定义如下:
struct psa_key_attributes_s
{
psa_key_type_t type;
psa_key_bits_t bits;
psa_key_lifetime_t lifetime;
psa_key_policy_t policy;
psa_key_id_t id;
};
成员 |
类型 |
说明 |
|---|---|---|
type |
psa_key_type_t |
密钥类型,例如AES密钥、RSA公钥、RSA密钥对、ECC公钥或ECC密钥对。通过 psa_set_key_type() 设置 |
bits |
psa_key_bits_t |
密钥长度,单位为位。例如AES-128填写128、RSA-2048填写2048、P-256填写256。通过 psa_set_key_bits() 设置 |
lifetime |
psa_key_lifetime_t |
密钥生命周期及存储位置。用于区分临时密钥、持久化密钥,以及密钥由本地软件还是安全硬件管理。通过 psa_set_key_lifetime() 设置 |
policy |
psa_key_policy_t |
密钥使用策略,包括允许的操作和算法,例如允许加密、解密、签名、验签,以及允许使用AES-GCM、RSA-OAEP或ECDSA等算法 |
id |
psa_key_id_t |
持久化密钥标识符。临时密钥通常不需要设置;持久化密钥通过 psa_set_key_id() 指定 |
备注
该结构体通常不直接访问内部成员,而是通过 psa_set_key_type()、psa_set_key_bits()、psa_set_key_usage_flags()、psa_set_key_algorithm() 等接口设置。
枚举定义¶
psa_status_t¶
操作状态码枚举定义如下:
typedef int32_t psa_status_t;
成员 |
说明 |
|---|---|
PSA_SUCCESS |
函数执行成功 |
PSA_ERROR_INVALID_HANDLE |
密钥标识无效 |
PSA_ERROR_NOT_PERMITTED |
密钥权限或算法策略不允许执行当前操作 |
PSA_ERROR_INVALID_SIGNATURE |
签名校验失败 |
PSA_ERROR_BUFFER_TOO_SMALL |
输出缓冲区空间不足 |
PSA_ERROR_NOT_SUPPORTED |
当前算法、曲线或密钥类型不支持 |
PSA_ERROR_INVALID_ARGUMENT |
输入参数无效 |
PSA_ERROR_INSUFFICIENT_ENTROPY |
随机数资源不足 |
PSA_ERROR_INSUFFICIENT_MEMORY |
内存不足 |
PSA_ERROR_BAD_STATE |
PSA Crypto未初始化或当前状态异常 |
psa_key_type_t¶
密钥类型枚举定义如下:
typedef uint16_t psa_key_type_t;
成员 |
说明 |
|---|---|
PSA_KEY_TYPE_ECC_KEY_PAIR(curve) |
ECC密钥对类型;用于ECDSA签名 |
PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve) |
ECC公钥类型;用于ECDSA验签 |
PSA_ECC_FAMILY_SECP_R1 |
SECP R1曲线族;作为 curve 参数取值;如secp256r1、secp384r1、secp521r1 |
PSA_ECC_FAMILY_SECP_K1 |
SECP K1曲线族;作为 curve 参数取值;如secp256k1 |
PSA_ECC_FAMILY_BRAINPOOL_P_R1 |
Brainpool P-R1曲线族;作为 curve 参数取值 |
psa_key_usage_t¶
密钥用途类型枚举定义如下:
typedef uint32_t psa_key_usage_t;
成员 |
说明 |
|---|---|
PSA_KEY_USAGE_SIGN_HASH |
允许使用密钥对摘要数据进行签名 |
PSA_KEY_USAGE_VERIFY_HASH |
允许使用密钥验证摘要数据的签名 |
PSA_KEY_USAGE_SIGN_MESSAGE |
允许使用密钥对原始消息进行签名 |
PSA_KEY_USAGE_VERIFY_MESSAGE |
允许使用密钥验证原始消息的签名 |
PSA_KEY_USAGE_EXPORT |
允许导出密钥 |
PSA_KEY_USAGE_COPY |
允许复制密钥 |
psa_algorithm_t¶
算法类型枚举定义如下:
typedef uint32_t psa_algorithm_t;
成员 |
说明 |
|---|---|
PSA_ALG_ECDSA(hash_alg) |
随机化ECDSA签名算法 |
PSA_ALG_DETERMINISTIC_ECDSA(hash_alg) |
确定性ECDSA签名算法;符合RFC 6979 |
PSA_ALG_ECDSA_ANY |
不指定摘要算法的ECDSA算法;通常用于已计算摘要场景 |
PSA_ALG_SHA_256 |
SHA-256摘要算法 |
PSA_ALG_SHA_384 |
SHA-384摘要算法 |
PSA_ALG_SHA_512 |
SHA-512摘要算法 |
应用逻辑流程图¶
示例代码¶
完整示例代码请查看https://github.com/UniRTOS/UniRTOS-Doc-Examples/blob/main/network/crypto/ecdsa_demo.c