公钥密码(PKE)开发指南
本文档以 security_demo_pke.c 为例,介绍在 HiDiTing 开发板上实现 ECDSA 签名验签的开发流程,以及 Security Unified PKE 接口的使用方法。
配套 Demo 实现了 Brainpool P256r1 ECDSA 自检,覆盖根据固定测试私钥生成公钥、公钥点检查、SHA-256、签名验签和篡改摘要拒绝。
PKE 背景知识
PKE 使用成对密钥完成非对称密码运算:
- 私钥必须保密,用于签名、解密或生成共享秘密。
- 公钥可以分发,用于验签、加密或生成共享秘密。
- 数字签名保护真实性、完整性和不可否认性,不提供数据保密。
- 公钥加密保护机密性,但不等同于数字签名。
- 密钥协商使通信双方计算出相同的共享秘密,协商结果通常还需要经过 KDF 派生才能作为业务密钥使用。
PKE 能力分类
| 能力 | 主要接口族 | 典型场景 |
|---|---|---|
| ECC 密钥生成 | ecc_gen_key |
设备身份密钥、临时密钥 |
| ECDSA/EdDSA 签名验签 | ecdsa_*、eddsa_* |
固件、证书、报文签名 |
| RSA 签名验签 | rsa_sign、rsa_verify |
兼容既有 PKI |
| RSA 加解密 | rsa_public_encrypt、rsa_private_decrypt |
小数据或密钥封装 |
| SM2 | sm2_* |
国密签名、验签和加解密 |
| ECDH/DH | ecc_gen_ecdh_key、dh_* |
会话密钥协商 |
| 大数和曲线点运算 | add_mod、mul_dot 等 |
密码协议底层运算 |
算法选择
| 场景 | 优先选择 | 说明 |
|---|---|---|
| 新项目设备签名 | 项目允许的安全 ECC 曲线 + ECDSA | 密钥较短、运算和存储开销较小 |
| 兼容既有证书体系 | RSA-PSS + SHA-256 或更强摘要 | 避免新设计继续使用 PKCS#1 v1.5 |
| 国密合规项目 | SM2 + SM3 | 需同时满足协议、证书和实现要求 |
| 会话密钥协商 | ECDH + HKDF | 未经 KDF 派生的共享秘密不得直接用作业务密钥 |
警告:
security_pke.h将 RSA PKCS#1 v1.5、SHA-1 和 SHA-224 标记为不建议使用的选项。算法、曲线和密钥长度还应符合产品安全规范及目标市场要求。
签名与加密
| 操作 | 使用的密钥 | 目标 |
|---|---|---|
| 私钥签名 | 签名方私钥 | 证明数据由私钥持有者签发 |
| 公钥验签 | 签名方公钥 | 验证签名和数据完整性 |
| 公钥加密 | 接收方公钥 | 只有对应私钥可解密 |
| 私钥解密 | 接收方私钥 | 恢复机密数据 |
“私钥加密、公钥解密”不能作为数字签名的通用实现描述。数字签名必须使用标准签名方案、正确编码和参数校验。
安全目标与能力边界
PKE 硬件加速解决的是密码运算问题,不自动建立可信身份、证书链或安全密钥生命周期。
| 安全目标 | PKE 能力 | 仍需配套的机制 |
|---|---|---|
| 消息真实性与完整性 | ECDSA/RSA/SM2 签名验签 | 可信公钥来源、证书验证和密钥吊销 |
| 小数据机密性 | RSA/SM2 公钥加密 | 标准填充、混合加密和密文协议定义 |
| 会话密钥建立 | ECDH/DH 计算共享秘密 | 对端公钥认证、HKDF、密钥确认 |
| 私钥保护 | 硬件运算可降低部分暴露面 | 安全生成、注入、存储、访问控制和清理 |
| 防重放 | 不直接提供 | 协议挑战值、序列号、时间窗 |
| 防回滚 | 不直接提供 | 固件安全版本和可信启动链 |
验签成功只说明“该签名与输入的公钥和消息匹配”。如果公钥来自不可信来源,验签成功仍不能证明业务身份可信。
公钥加密不适合直接处理大块业务数据。常见安全设计是使用随机对称密钥加密业务数据,再使用公钥算法保护或协商该对称密钥。
模块设计
PKE 对外接口位于 security_pke.h。Service Layer 对输入结构体、缓冲区和算法参数进行封装,驱动层调度 PKE 硬件运算,HAL 和 Hi3322 Porting 负责寄存器与平台适配。签名前通常先通过 HASH 模块计算摘要,密钥生成和签名过程还可能依赖安全随机数。
主要代码位置:
| 层级 | 代码位置 | 作用 |
|---|---|---|
| 对外接口 | src/include/driver/security_unified/security_pke.h | PKE 类型、结构体和 UAPI |
| 服务层 | src/drivers/drivers/driver/security_unified/service_layer/pke.c | PKE 服务封装 |
| 驱动层 | src/drivers/drivers/driver/security_unified/drv_code/pke | ECC、RSA、SM2 和大数运算 |
| HAL | src/drivers/drivers/hal/security_unified | PKE 硬件抽象 |
| 芯片适配 | src/drivers/chips/3322/porting/security_unified | Hi3322 PKE 能力配置 |
参数与配置说明
HiDiTingV100 LiteOS 和 SELiteOS 的 PKE 能力存在配置差异,编写示例时必须以目标固件的配置文件为准。
常用配置如下:
| 配置 | 作用 |
|---|---|
CONFIG_SECURITY_UNIFIED_SUPPORT_PKE |
使能 PKE 模块;SELiteOS 配置中显式定义 |
CONFIG_PKE_SUPPORT_ECC_GEN_KEY |
使能 ECC 密钥生成 |
CONFIG_PKE_SUPPORT_ECC_SIGN |
使能 ECC 签名验签 |
CONFIG_PKE_SUPPORT_ECC_BP256R |
使能 Brainpool P256r1 |
CONFIG_PKE_SUPPORT_ECC_FIPS_P256R |
使能 FIPS P-256 |
CONFIG_PKE_SUPPORT_RSA |
使能 RSA |
CONFIG_PKE_SUPPORT_SM2 |
使能 SM2 |
本 Demo 使用 UAPI_DRV_CIPHER_PKE_ECC_TYPE_RFC5639_P256(Brainpool P256r1)。Hi3322 LiteOS 安全配置已定义 ECC 密钥生成、ECC 签名、公钥点检查和 Brainpool P256r1 所需能力宏;diting-community 目标另通过 CONFIG_ENABLE_SECURITY_SAMPLE 编入 security_sample。移植到其他目标时,必须再次核对配置头和组件清单。
Brainpool P256r1 的 Montgomery/Jacobian 参数位于 src/drivers/drivers/hal/security_unified/common/curve_param/brainpool_256r1.c。当前实现中的 mont_b 与 g_jac_y 分别满足 b × 2^256 mod p 和 Gy × 2^256 mod p;移植或合并旧分支时应以当前参数文件为准,不能沿用未经模运算校验的旧常量。
需要准备:
- 32 字节私钥缓冲区。
- 公钥 X/Y 坐标缓冲区。
- 32 字节 SHA-256 摘要。
- 签名 R/S 缓冲区。
- 消息和篡改摘要缓冲区。
- 统一错误处理和安全清零函数。
API 接口列表
ECC/ECDSA
| 接口函数 | 说明 |
|---|---|
| uapi_drv_cipher_pke_ecc_gen_key | 生成 ECC 密钥对,或根据输入私钥生成公钥 |
| uapi_drv_cipher_pke_ecdsa_sign | 对摘要执行 ECDSA 签名 |
| uapi_drv_cipher_pke_ecdsa_verify | 验证 ECDSA 签名 |
| uapi_drv_cipher_pke_ecdsa_verify_s | 安全加固验签;成功返回后还需比较输出 v 与签名 r |
| uapi_drv_cipher_pke_check_dot_on_curve | 检查公钥点是否位于指定曲线上 |
RSA
| 接口函数 | 说明 |
|---|---|
| uapi_drv_cipher_pke_rsa_sign | RSA 私钥签名 |
| uapi_drv_cipher_pke_rsa_verify | RSA 公钥验签 |
| uapi_drv_cipher_pke_rsa_public_encrypt | RSA 公钥加密 |
| uapi_drv_cipher_pke_rsa_private_decrypt | RSA 私钥解密 |
SM2 与密钥协商
| 接口函数 | 说明 |
|---|---|
| uapi_drv_cipher_pke_sm2_dsa_hash | 计算 SM2 签名所需摘要 |
| uapi_drv_cipher_pke_sm2_sign | SM2 签名 |
| uapi_drv_cipher_pke_sm2_verify | SM2 验签 |
| uapi_drv_cipher_pke_sm2_public_encrypt | SM2 公钥加密 |
| uapi_drv_cipher_pke_sm2_private_decrypt | SM2 私钥解密 |
| uapi_drv_cipher_pke_ecc_gen_ecdh_key | 计算 ECDH 共享秘密 |
| uapi_drv_cipher_pke_dh_gen_key | 生成 DH 公私钥 |
| uapi_drv_cipher_pke_dh_compute_key | 计算 DH 共享秘密 |
快速跑通 PKE Demo
功能说明
AT+SECPKE 示例完成以下检查:
- 使用确定性的 32 字节全宽测试私钥,调用 ECC 密钥生成接口得到对应公钥。
- 调用公钥点检查接口,确认生成的公钥位于 Brainpool P256r1 曲线上。
- 对固定消息计算 SHA-256 摘要。
- 使用私钥对摘要执行 ECDSA 签名。
- 使用公钥、摘要和签名执行验签。
- 修改摘要中的一个比特,再次验签,必须失败。
- 清理输入/输出私钥、摘要、篡改摘要和签名缓冲区。
当前固定测试私钥为 7a030a2a840b11f6cf1717f2b7dc62eba26f782b63d78f1bedc0497bbb1b7961,用于获得可复现的公钥和测试输入,仅允许用于示例代码,不得用于量产产品。不要将私钥简化为 1 或 2:这类小标量虽处于数学有效范围内,但会令公钥成为基点的小倍数,使同时点乘验签更容易进入相关点或同点相加的特殊边界,不能代表正常密钥路径。
示例实现位于 /samples/native_samples/security/security_demo_pke.c,命令注册位于 /samples/native_samples/security/security_demo.c。该示例用于驱动功能自检,不包含证书链、可信公钥分发或量产私钥注入逻辑。
操作流程
为什么示例选择 ECDSA:
- 同时覆盖 ECC 密钥生成、HASH、签名和验签。
- 签名数据和公钥长度相对较小,适合嵌入式演示。
- 篡改测试能直观展示数字签名的完整性保护能力。
- RSA、SM2 和密钥协商可在同一框架下扩展,无需在单个基础示例中覆盖全部算法。
编译
Demo 已接入 diting-community 目标。完成一站式 CLI 环境配置后执行:
构建成功后,使用一站式 CLI 烧写固件并打开 UART2 串口监视器。以下为 Windows USB DFU 示例;将 COM3 替换为实际日志串口,其他平台和串口烧写参数参见一站式 CLI 开发环境使用指南。
fbb flash -f "$env:FBB_SDK_DIR\output\3322\fwpkg\diting-community.fwpkg" --chip 3322 -d --timeout 180
fbb monitor --port COM3 --baud 750000
说明:本文示例命令以一站式 CLI 为主。实际开发可从以下三种环境中选择,推荐使用一站式 CLI。
| 开发环境 | 适用场景 | 使用指南 |
|---|---|---|
| 一站式 CLI(推荐) | 快速完成目标选择、构建、烧录和串口监视 | 一站式 CLI 开发环境使用指南 |
| HiSpark Studio for VS Code | 图形化编辑、编译、烧录和调试 | HiSpark Studio for VS Code 开发环境使用指南 |
| WSL 与 Docker | 在 Windows 上使用一致的 Linux 容器构建环境 | WSL 与 Docker 环境使用指南 |
或使用一站式 CLI:
预期固件:
烧录和串口监视参见一站式 CLI 开发环境使用指南。
使用方式
- 烧录并复位设备。
- 打开串口监视器。
- 执行
AT+SECPKE。 - 保存曲线类型、失败阶段和完整返回码。
命令返回 OK 且日志最后出现 [SEC][PKE] PASS 才表示示例通过。也可以执行 AT+SECDEMOALL 运行 AES-GCM、HASH、PKE、密钥管理和 mbed TLS 五项安全示例;五项汇总及 [SEC][ALL] 均为 PASS 才表示全部通过。
验证说明: Demo 已完成
diting-community目标的完整编译、最终 ELF 链接及固件 BIN 生成验证。
预期结果
[SEC][PKE] start
[SEC][PASS] ECDSA derive public key
[SEC][PASS] ECDSA public point check
[SEC][PASS] ECDSA public point is on curve
[SEC][PASS] ECDSA message SHA-256
[SEC][PASS] ECDSA sign
[SEC][PASS] ECDSA verify
[SEC][PASS] ECDSA tampered digest rejected, ret=0x........
[SEC][PKE] PASS
OK
其中 0x........ 是平台实际返回的验签失败错误码;篡改摘要被拒绝是预期结果。ECDSA 使用运行时随机数,签名 R/S 每次可能不同,因此示例只判断签名能否正确验签,不比较固定签名字节。
文件结构与代码走读
文件结构
配套 Demo 位于以下路径:
/samples/native_samples/security/
├── CMakeLists.txt # Security Demo 编译配置
├── security_demo.c # AT 命令注册与汇总入口
├── security_demo.h # 公共函数声明
├── security_demo_cipher_hash.c # AES-GCM 与 SHA-256 示例
├── security_demo_pke.c # ECDSA 签名验签示例
├── security_demo_key.c # HKDF 与 Keyslot 示例
├── security_demo_mbedtls.c # mbed TLS SHA-256 标准向量示例
├── security_demo_utils.c # 公共校验、日志与安全清理
├── security_demo_utils.h # 公共辅助函数声明
└── README.md # 安全示例运行说明
各文件职责
| 文件 | 职责 | 关键内容 |
|---|---|---|
security_demo_pke.c |
实现 Brainpool P256r1 ECDSA 自检 | 标准向量、自检流程和错误处理 |
security_demo.c |
注册安全示例 AT 命令 | AT+SECAESGCM、AT+SECHASH、AT+SECPKE、AT+SECKEY、AT+SECMBEDTLS、AT+SECDEMOALL |
security_demo_mbedtls.c |
实现 mbed TLS SHA-256 自检 | abc 标准向量与公共 mbedtls_sha256() API |
security_demo_utils.c |
提供公共结果检查和清理能力 | PASS/FAIL 输出、字节比较、安全清零 |
CMakeLists.txt |
定义 security_sample 组件 |
源文件、头文件、编译宏和组件链接 |
代码走读
本节结合 /samples/native_samples/security/security_demo_pke.c 说明实现步骤。
步骤 1:准备结构体
根据 security_pke.h 准备:
uapi_drv_cipher_pke_data_t:私钥和摘要。uapi_drv_cipher_pke_ecc_point_t:公钥 X/Y。uapi_drv_cipher_pke_ecc_sig_t:签名 R/S。
所有结构体的 length 必须与所选曲线一致,缓冲区不足可能导致失败或越界风险。
步骤 2:生成或恢复公钥
示例将上述 32 字节全宽测试私钥复制到 input_private,再向 uapi_drv_cipher_pke_ecc_gen_key 传入该缓冲区,获得与之对应的公钥。量产业务应使用经过审计的密钥生成、注入和存储流程,不应复制示例私钥。
ret = uapi_drv_cipher_pke_ecc_gen_key(
curve_type,
&input_private_key,
&output_private_key,
&output_public_key);
步骤 3:校验公钥点
公钥来自外部通信、证书或存储介质时,在参与敏感运算前应校验点是否合法:
bool is_on_curve = false;
ret = uapi_drv_cipher_pke_check_dot_on_curve(
curve_type, &output_public_key, &is_on_curve);
接口返回成功且 is_on_curve 为 true,才能继续使用该公钥。
具体参数约束以 uapi_drv_cipher_pke_check_dot_on_curve 为准。
步骤 4:计算摘要
调用 SHA-256 接口计算消息摘要。签名端与验签端必须使用完全一致的消息编码和摘要算法。
步骤 5:签名
ECDSA 签名通常会使用随机数,因此即使私钥和摘要相同,签名结果也不一定每次相同。示例应验证签名能否通过验签,不应假定签名字节固定。
步骤 6:验签和负向测试
随后复制摘要并修改一个比特,再次验签。原摘要验签成功且篡改摘要验签失败,测试才通过。
步骤 7:清理
示例结束前清理:
- 输入私钥
input_private和输出私钥output_private。 - 原摘要
digest和篡改摘要tampered_digest。 - 签名缓冲区
sig_r和sig_s。
不应将完整私钥或共享秘密打印到串口日志。
基于 PKE Demo 开发应用
配套 Demo 可以通过 AT 命令触发板端回归,但自定义 PKE 应用应从业务任务或服务直接调用 PKE 接口或可复用的运行函数,并为新增算法补充标准向量、异常处理和敏感数据清理逻辑。
代码清单
- 新增或修改示例源文件
- 补充函数声明与编译配置
- 从业务任务或服务调用运行函数并处理结果
- 增加标准测试向量
- 增加负向测试与资源释放路径
- 如需串口回归,再注册独立 AT 命令(可选)
CMakeLists.txt 修改示例
在上层 samples/native_samples/CMakeLists.txt 中按功能宏加入示例目录:
在目标 config.py 中添加 CONFIG_ENABLE_SECURITY_SAMPLE,并将 security_sample 加入目标组件列表。
关键代码片段
以下代码展示业务入口直接复用现有自检函数的基本方式:
扩展建议:
密码运算功能与设备身份方案应分别进行验证。
| 项目 | 开发验证 | 量产要求 |
|---|---|---|
| 私钥 | 固定公开测试私钥 | 在受控环境生成或注入,不进入源码仓库 |
| 公钥 | 由测试私钥推导 | 绑定证书、设备身份或可信根 |
| 随机数 | 验证接口依赖是否正常 | 评估熵源健康状态和异常处理 |
| 验签 | 正确消息成功、篡改消息失败 | 同时验证证书链、用途、有效期和吊销状态 |
| 日志 | 可输出阶段和公开测试数据 | 不输出私钥、共享秘密和敏感中间值 |
| 故障恢复 | 重新运行测试 | 明确密钥吊销、设备返修和身份重置流程 |
量产前至少确认:
- 私钥生成、签名或注入环境具有可信熵源和访问控制。
- 签名私钥与验签公钥的归属、用途和版本可追踪。
- 外部公钥已经完成格式、曲线点、证书链和用途检查。
- ECDH/DH 已认证对端公钥,并使用 KDF 派生不同用途的密钥。
- 签名方案、填充方式和摘要算法符合项目安全基线。
- 已设计密钥泄露后的吊销、换钥和固件升级路径。
测试验证
完成一站式 CLI 环境配置后执行:
# 编译固件,编译生成的固件从 output/3322/fwpkg 中获取 diting-community.fwpkg
fbb set-target pack_diting_community
fbb build
- 烧录固件并启动设备。
- 从业务任务或测试任务调用
security_demo_run_pke()或自定义运行函数。 - 保存函数结果、错误码和必要的脱敏日志。
- 确认所有正向检查通过,并且篡改输入被拒绝。
- 需要板端串口回归时,可选用配套 AT 命令触发同一运行函数。
注意事项
- 私钥不得写入普通日志、崩溃转储或可读配置文件。
- 示例固定私钥只能用于功能测试。
- 公钥来自不可信来源时必须进行格式、长度和曲线点校验。
- ECDSA 签名依赖高质量随机数;随机数失效可能泄露私钥。
- ECDH/DH 输出是共享秘密,应再经过 HKDF 等 KDF 派生不同用途的会话密钥。
- RSA 新设计优先使用 PSS 签名和 OAEP 加密,不建议使用 PKCS#1 v1.5。
- 签名对象必须有明确、无歧义的序列化规则,避免不同字段拼接成相同字节流。
- 验签成功不仅要检查接口返回值;使用安全加固接口时,还必须完成接口文档要求的额外比较。
- 认证或验签失败后,不得继续处理被保护的数据。
- PKE 运算可能占用较多栈空间和执行时间。进行实板测试时,应记录栈余量和执行时间。
常见编译错误
错误码解析
Security Unified 组合错误码定义位于 /src/drivers/drivers/hal/security_unified/include/common_include/crypto_errno.h,可按以下方式解析:
env = (error >> 28) & 0xF;
layer = (error >> 24) & 0xF;
module = (error >> 20) & 0xF;
error_code = error & 0xFF;
| 字段 | 值 | 含义 |
|---|---|---|
| ENV | 0x1/0x2/0x3 | Linux/iTrustee/OP-TEE |
| ENV | 0x4/0x5/0x6 | LiteOS/SELiteOS/无 OS |
| ENV | 0x7/0x8 | FreeRTOS/AliOS |
| LAYER | 0x1/0x2 | UAPI/Dispatch |
| LAYER | 0x3/0x4/0x5 | KAPI/Driver/HAL |
| MODULE | 0x3 | PKE 模块 |
PKE 常用错误类型如下:
| 名称 | 低 8 位 | 含义 | 优先检查项 |
|---|---|---|---|
ERROR_INVALID_PARAM |
0x01 | 参数取值无效 | 曲线、长度、密钥和算法枚举 |
ERROR_PARAM_IS_NULL |
0x02 | 必填指针为空 | 私钥、公钥、摘要和签名缓冲区 |
ERROR_NOT_INIT |
0x03 | 模块未初始化 | 系统安全环境和 PKE 初始化状态 |
ERROR_UNSUPPORT |
0x04 | 配置或能力不支持 | ECC、RSA、SM2 和目标曲线配置宏 |
ERROR_CHN_BUSY |
0x07 | PKE 通道繁忙 | 并发运算和异常退出后的资源释放 |
ERROR_PKE_ECDSA_VERIFY_CHECK |
0x1A | ECDSA 验签失败 | 摘要、公钥、签名和曲线 |
ERROR_PKE_SECURITY_STRENGTH_NOT_MATCH |
0x1E | 安全强度不匹配 | 曲线、RSA 位宽和 HASH 算法 |
ERROR_MALLOC |
0x41 | 内存申请失败 | 堆余量和临时大数缓冲区 |
ERROR_PKE_LOGIC |
0xA1 | PKE 硬件逻辑错误 | PKE 状态和驱动日志 |
ERROR_PKE_WAIT_DONE_TIMEOUT |
0xB7 | PKE 等待完成超时 | 参数规模、通道锁和硬件状态 |
说明: 某些底层接口可能直接返回通用错误值或
0xFFFFFFFF。只有符合组合错误码格式的返回值才能按 ENV、LAYER、MODULE 和 Error Code 解析。
常见运行问题
ECC 密钥生成参数错误
- 私钥、公钥 X/Y 和输出结构体长度必须与曲线位宽一致。
- 固定私钥必须位于所选曲线允许的范围内。
- 输入输出结构体的数据指针必须有效。
- 所选曲线必须在目标配置中启用。
ECDSA 签名失败
- 检查摘要长度和摘要算法是否匹配。
- 检查私钥长度及取值范围。
- 检查签名 R/S 缓冲区长度。
- 检查安全随机数能力和 PKE 硬件状态。
- 检查 PKE 通道是否繁忙或发生等待超时。
ECDSA 验签失败
- 验签公钥是否与签名私钥匹配。
- 签名端与验签端的曲线类型是否一致。
- 摘要内容、长度和消息序列化方式是否一致。
- 签名 R/S 的编码顺序、长度和字节序是否正确。
- 公钥点是否位于指定曲线上。
安全加固验签仅检查返回值
调用 uapi_drv_cipher_pke_ecdsa_verify_s 时,接口返回成功后还必须比较输出 v 与输入签名 r。缺少该比较时,不得判定验签通过。
RSA 加解密失败
- 检查模数长度和密钥结构体字段长度。
- 检查签名端与验签端、加密端与解密端的填充方案是否一致。
- 检查 OAEP/PSS 使用的 HASH 类型。
- 检查输入长度是否超过填充方案允许的范围。
- 检查输出缓冲区长度。
- 新项目不应继续使用 PKCS#1 v1.5 等不建议的方案。
SM2 签名验签不一致
SM2 摘要依赖消息、用户 ID 和公钥。签名端与验签端必须使用相同的用户 ID、消息编码和公钥参数。
常见编译与链接问题
| 错误现象 | 原因 | 解决方法 |
|---|---|---|
找不到 security_pke.h |
安全头文件路径未加入组件 | 检查 PRIVATE_HEADER 是否包含 src/include/driver |
| PKE 接口链接失败 | PKE 驱动或示例组件未参与链接 | 检查目标组件和 PKE 配置宏 |
AT+SECPKE 不存在 |
AT 命令未注册或仍在运行旧固件 | 检查 security_sample 和烧录固件版本 |
| ECDSA 签名或验签失败 | 曲线、长度、摘要或密钥不一致 | 核对曲线枚举及 32 字节缓冲区 |
| 增量编译结果异常 | 旧对象文件或缓存掩盖配置变化 | 清理构建缓存后执行完整构建 |
调试方法
- 确认所选曲线在目标配置文件中已启用。
- 检查私钥、公钥 X/Y、摘要和签名 R/S 的长度是否一致。
- 公钥来自外部时先执行曲线点检查。
- 签名失败时检查摘要长度、私钥范围和安全随机数能力。
- 验签失败时确认签名端与验签端的消息编码、HASH 算法、曲线和公钥完全一致。
- RSA 失败时检查模数长度、填充方案、摘要类型和输入长度。
- SM2 失败时检查用户 ID、ZA 摘要和公钥参数是否一致。
- 使用完整十六进制返回值解析运行环境、软件层级、PKE 模块和具体错误类型。
问题反馈信息
提交 Issue 或请求技术支持时,应提供 SDK 版本、芯片与开发板、构建目标、失败接口、完整十六进制返回值、曲线或 RSA 位宽、摘要类型、输入长度、最小复现步骤、预期结果和实际日志。不得提交设备私钥、共享秘密、证书私钥或生产环境凭据。