如何在MbedTLS/OpenSSL中自动添加SHA-256的OID前缀?
问题解决:MbedTLS验证OpenSSL签名哈希失败的处理方案
核心问题根源
OpenSSL用私钥签名哈希时,默认会将裸哈希包装成ASN.1 DigestInfo结构(包含SHA-256算法OID前缀+裸哈希),而你直接通过mbedtls_sha256()生成的是无OID的裸哈希,两者结构不一致,导致mbedtls_pk_verify()比对失败。
两种常规解决方法
方法1:让MbedTLS自动处理DigestInfo包装(推荐)
利用MbedTLS内置的哈希算法标识参数,让库自动完成裸哈希到DigestInfo的包装,完全适配OpenSSL的签名格式:
- 初始化PK上下文并加载验证用的公钥;
- 用
mbedtls_sha256()或mbedtls_md()系列函数生成本地文件的SHA-256裸哈希; - 调用
mbedtls_pk_verify()时指定哈希算法为MBEDTLS_MD_SHA256,库会自动构造对应的DigestInfo结构,再与解密后的签名内容比对。
示例代码片段:
// 假设已完成pk_ctx初始化(加载公钥)、sig为接收的签名数据、sig_len为签名长度 // hash为本地计算的32字节SHA-256裸哈希 int ret; ret = mbedtls_pk_verify(&pk_ctx, MBEDTLS_MD_SHA256, hash, 0, sig, sig_len); if(ret == 0) { // 验证成功 } else { // 验证失败,处理错误码 }
方法2:手动构造DigestInfo结构(适合资源受限场景)
如果固件资源紧张,可直接硬编码SHA-256对应的DigestInfo前缀,再与本地哈希拼接:
- SHA-256的DigestInfo固定前缀:
0x30 0x31 0x30 0x0D 0x06 0x09 0x60 0x86 0x48 0x01 0x65 0x03 0x04 0x02 0x01 0x05 0x00 0x04 0x20 - 将上述19字节前缀与32字节的本地SHA-256哈希拼接成51字节缓冲区,再与解密后的签名内容直接比对。
这种方法无需依赖MbedTLS的额外接口,但换用其他哈希算法时需修改前缀,灵活性较低。
关键注意点
OpenSSL的签名流程默认遵循PKCS#1 v1.5标准,MbedTLS的mbedtls_pk_verify()默认也适配该标准,只要正确指定哈希算法参数,就能自动完成格式对齐,无需手动处理OID拼接。
内容的提问来源于stack exchange,提问作者kackle123
相关产品推荐
相关产品推荐

