OpenSSL 为 C 提供 libcrypto 和 libssl,并通过绑定为 Node.js、Python、PHP 和 Ruby 提供它们,此外还有大多数人最先接触到的 openssl 命令。本页的事实基于 Alpine 3.24.2 发行版的软件包 OpenSSL 3.5.9(3.5 长期支持版本线)检查得出;当时上游最新的版本是 3.6.5 和 4.0.3,这些版本的行为可能有所不同。
EVP_DigestSign 和 openssl dgst -sign 生成的 ECDSA 签名都是 ASN.1 DER——在 P-256 上为 70 到 72 字节。nonce 是随机的,除非把 nonce-type 参数设为 1(OpenSSL 3.2+),这样能复现 RFC 6979 的 P-256 测试向量;在命令行上,只能像示例那样通过 pkeyutl 使用该参数。s 没有经过规范化,验证时接受 high-S。EVP_PKEY_sign 对你自行计算的摘要签名。
格式错误的输入会报错,而不是返回验证失败:对于 64 字节的原始 r‖s 签名,EVP_DigestVerify 返回 -1,CLI 也如实报告了这一点。openssl dgst -verify 对正确的签名输出 Verified OK,对针对其他数据的有效签名输出 Verification failure,对不是 DER 的 64 字节数据输出 Error verifying data——因此在 3.5.9 中,可以根据措辞区分格式问题与伪造签名。可以用 DER ⇄ 原始格式转换器转换原始签名,或者让 OpenSSL 命令生成器组装正确的调用命令。
曲线涵盖 P-224 到 P-521、secp256k1 和 Brainpool r1 曲线,另有 Ed25519 和 Ed448。自 3.5 起,默认提供程序还实现了 ML-KEM、ML-DSA 和 SLH-DSA,以及 TLS 混合组 X25519MLKEM768。私钥格式为 PKCS#8(未加密或加密)或 SEC1,公钥格式为 SPKI 或证书:genpkey 写出 -----BEGIN PRIVATE KEY-----,旧式的 openssl ec 写出 -----BEGIN EC PRIVATE KEY-----——标为 EC 的文件始终是私钥。
人们搜索的错误信息大多来自密钥加载——no start line、header too long,以及解码器报出的 unsupported——本页链接的错误页面都有说明。