跳到主要内容
ecdsa.com
C

wolfSSL (wolfCrypt)

wolfSSL 的嵌入式 TLS 库及 wolfCrypt 密码库:ECDSA 对你提供的摘要签名并输出 DER,验证调用的返回码与验证结论相互独立——而功能集完全取决于构建方式。
许可证
GPL-3.0-only
检查的版本
5.9.4 ·
源代码
github.com/wolfSSL/wolfssl
文档
www.wolfssl.com/documentation/manuals/wolfssl/

兼容性概览

ECDSAEdDSA后量子

ECDSA 曲线
P-224P-256P-384P-521
EdDSA
Ed25519
公钥格式
spki-der
私钥格式
sec1-der

wolfSSL 面向嵌入式系统和 FIPS 部署,几乎一切都是编译期选项:曲线、EdDSA 变体、确定性 nonce、后量子算法和 PEM 支持,都随 ./configure 标志而启用或消失。本页的事实基于 Alpine 3.24.2 中 wolfSSL 5.9.4 的软件包,构建时启用了 HAVE_ECC、HAVE_ED25519、HAVE_CURVE25519 和 WOLFSSL_HAVE_MLKEM,但没有启用 HAVE_ED448、HAVE_DILITHIUM、Koblitz 或 Brainpool 曲线,也没有启用 WOLFSSL_ECDSA_DETERMINISTIC_K。自定义构建在其中每一项上都可能不同。

wc_ecc_sign_hash 对你计算好的摘要签名并返回 DER;对于原始签名,wc_ecc_verify_hash_ex 以整数形式接收 r 和 s。验证有两个输出:函数的返回码表示它能否运行,int *res 参数则保存验证结论。把 64 字节的原始签名传给 wc_ecc_verify_hash,返回 -171(ECC ASN1 bad key data, invalid input),结论为 0;只检查返回码或只检查结论的代码,都会错误处理两种情况之一。示例会同时打印两者。

在这个构建中,nonce 是随机的(RFC 6979 确定性签名需要 WOLFSSL_ECDSA_DETERMINISTIC_K),s 没有经过规范化,high-S 签名也能验证通过。支持的曲线从 P-224 到 P-521;除非启用,否则没有 secp256k1 和 Brainpool。Ed25519 可用,ML-KEM-768 通过 wc_MlKemKey_* 完成了封装和解封装;这个构建中没有 ML-DSA(Dilithium)。

密钥以 DER 形式传递:wc_EccPublicKeyToDer 写出 SPKI,wc_EccKeyToDer 写出 SEC1 ECPrivateKey;由于该软件包设置了 WOLFSSL_DER_TO_PEM,也可以转换为 PEM(wc_DerToPem)。Alpine 软件包声明的许可证为 GPL-3.0-only;商业许可证由 wolfSSL Inc. 另行出售。可以用 DER ⇄ 原始格式转换器对照其他协议栈检查编码。

事实及其依据的检查

以下内容均非抄自文档。检查脚本 content/libraries/verify/wolfssl/run.sh 于2026年10月20日在容器镜像 alpine:3.24.2 中运行了 wolfSSL (wolfCrypt) 5.9.4;本页内容必须与它的输出一致,每条事实都列出了对应的输出行。

  • ECDSA 签名编码

    der

    wc_ecc_sign_hash 返回 DER;wc_ecc_verify_hash_ex 验证以整数形式给出的 r 和 s。

    检查记录
    fact ecdsa-signature-encoding = der
    evidence ecdsa-signature-encoding: wc_ecc_verify_hash_ex with r and s as integers verifies: 1
  • ECDSA 的 nonce

    random

    这个构建没有 WOLFSSL_ECDSA_DETERMINISTIC_K,使用随机 nonce。

    检查记录
    fact ecdsa-nonce = random
    evidence ecdsa-nonce: this build lacks WOLFSSL_ECDSA_DETERMINISTIC_K, so RFC 6979 signing is not available
  • 签名时的 low-S

    either

    s 没有经过规范化:64 个签名中出现了 high-S 值。

    检查记录
    fact ecdsa-low-s-sign = either
  • 验证时的 high-S

    accepts-high-s

    把 s 替换为 n − s 的 DER 签名验证通过。

    检查记录
    fact ecdsa-low-s-verify = accepts-high-s
  • 签名调用对哪些内容做哈希

    takes-digest

    wc_ecc_sign_hash 和 wc_ecc_verify_hash 处理的是调用方计算好的摘要。

    检查记录
    fact ecdsa-prehash = takes-digest
    evidence ecdsa-prehash: wc_ecc_sign_hash and wc_ecc_verify_hash take a digest the caller computed
  • 格式错误的 ECDSA 签名

    returns-error

    原始 r‖s 签名让 wc_ecc_verify_hash 返回 -171(ECC ASN1 bad key data, invalid input),验证结论为 0。

    检查记录
    fact ecdsa-malformed-signature = returns-error
    evidence ecdsa-malformed-signature: wc_ecc_verify_hash on raw r||s: return code -171 (ECC ASN1 bad key data, invalid input), result 0
  • ECDSA 曲线

    P-224P-256P-384P-521

    这个构建支持 P-224、P-256、P-384 和 P-521;secp256k1 和 brainpoolP256r1 的密钥生成失败。

    检查记录
    fact ecdsa-curves = P-224, P-256, P-384, P-521
  • EdDSA

    Ed25519

    支持 Ed25519;这个构建没有设置 HAVE_ED448。

    检查记录
    fact eddsa = Ed25519
    evidence eddsa: HAVE_ED448 is not set in this build
  • 后量子算法

    ML-KEM

    ML-KEM-768 通过 wc_MlKemKey_* 完成了封装与解封装的往返;这个构建没有设置 HAVE_DILITHIUM(ML-DSA)。

    检查记录
    fact pqc = ML-KEM
    evidence pqc: HAVE_DILITHIUM (ML-DSA) is not set in this build
  • 公钥格式

    spki-der

    wc_EccPublicKeyToDer 和 wc_EccPublicKeyDecode 处理 SPKI DER,解码得到的密钥成功验证了签名。

    检查记录
    fact public-key-formats = spki-der
  • 私钥格式

    sec1-der

    wc_EccKeyToDer 写出 SEC1 ECPrivateKey(P-256 为 121 字节),wc_EccPrivateKeyDecode 能把它读回。

    检查记录
    fact private-key-formats = sec1-der
    evidence private-key-formats: wc_EccKeyToDer writes a SEC1 ECPrivateKey of 121 bytes
    evidence private-key-formats: WOLFSSL_DER_TO_PEM is set in this build

用法

计算哈希,用 P-256 签名并验证,同时打印返回码和验证结论。
#include <wolfssl/options.h>
#include <wolfssl/wolfcrypt/ecc.h>
#include <wolfssl/wolfcrypt/random.h>
#include <wolfssl/wolfcrypt/sha256.h>
#include <stdio.h>

int main(void) {
    WC_RNG rng;
    ecc_key key;
    unsigned char digest[32], sig[ECC_MAX_SIG_SIZE];
    word32 sig_len = sizeof sig;
    int verified = 0;
    const unsigned char msg[] = "order #1042 approved";

    wc_InitRng(&rng);
    wc_ecc_init(&key);
    wc_ecc_make_key_ex(&rng, 32, &key, ECC_SECP256R1);

    /* wolfCrypt signs a digest you computed and returns DER. */
    wc_Sha256Hash(msg, sizeof msg - 1, digest);
    wc_ecc_sign_hash(digest, sizeof digest, sig, &sig_len, &rng, &key);
    /* The return code says whether verification ran; "verified" holds the verdict. */
    int rc = wc_ecc_verify_hash(sig, sig_len, digest, sizeof digest, &verified, &key);
    printf("rc: %d, verified: %d, DER starts with 0x%02x\n", rc, verified, sig[0]);

    wc_ecc_free(&key);
    wc_FreeRng(&rng);
    return 0;
}

代码片段测试工具会在容器镜像 alpine:3.24.2 中原样运行每个示例,只要输出不匹配,运行就会失败。

环境准备
apk add --no-cache -q build-base wolfssl-dev=5.9.4-r0 >/dev/null
命令
cc -o usage usage.c -lwolfssl && ./usage
输出必须匹配(正则表达式)
rc: 0, verified: 1, DER starts with 0x30

库