You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OpenSSL Ed25519签名验证C/C++代码示例及正确性咨询

OpenSSL Ed25519 验签功能实现说明

官方文档提供的Ed25519算法C代码可直接用于C/C++程序的消息签名场景,但未配套给出签名验证的对应实现,即和文档中do_sign()匹配的do_verify()函数。
以下是对自行编写的验签代码的校验结论,以及可直接使用的正确实现:


原有代码存在的问题

你写的实现有3个容易出故障的隐患:

  • 缺少空指针防护:EVP_MD_CTX_new()申请内存失败时会返回NULL,直接传入后续API会触发空指针崩溃。
  • 运算符优先级不规范:C语言中==优先级高于&&,现有判断逻辑虽然靠短路规则不会直接返回错误结果,但后续调整判断条件时极易出现逻辑偏差,且所有OpenSSL API的返回值应该单独校验,不建议写在同一个链式判断里。
  • 错误类型混淆:EVP_DigestVerify()的返回值有三种:验签成功返回1,签名不匹配返回0,参数错误/内部运行错误返回-1。原有写法会把运行错误和验签失败都归为返回0,排查问题时无法区分是签名本身不对,还是程序传参出了问题。

可直接使用的正确验签实现

int do_verify(EVP_PKEY* pkey,
    const unsigned char* sig, size_t sig_len,
    const unsigned char* msg, size_t msg_len) {
    int ret = 0;
    EVP_MD_CTX* md_ctx = EVP_MD_CTX_new();
    if (md_ctx == NULL) {
        return -1; // 内存申请失败
    }

    // Ed25519为无哈希的原生签名算法,不需要传入摘要类型,第三、第四个参数传NULL符合官方规范
    if (EVP_DigestVerifyInit(md_ctx, NULL, NULL, NULL, pkey) != 1) {
        ret = -1;
        goto cleanup;
    }

    int verify_ret = EVP_DigestVerify(md_ctx, sig, sig_len, msg, msg_len);
    if (verify_ret == 1) {
        ret = 1; // 验签通过
    } else if (verify_ret == 0) {
        ret = 0; // 签名不匹配
    } else {
        ret = -1; // 参数非法、内部运算错误等异常
    }

cleanup:
    EVP_MD_CTX_free(md_ctx);
    return ret;
}

补充说明:Ed25519的签名固定长度为64字节,API内部已经做了签名长度校验,如果传入的sig_len不是64,会直接返回-1抛出参数错误,不需要业务层额外加判断。


内容的提问来源于stack exchange,提问作者Decaf Sux

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 01:36:15