ring 只提供少量算法,采用源自 BoringSSL 的汇编代码和防误用的 API:无法自行选择 nonce,无法对预先计算的摘要签名,也无法加载不常见格式的密钥。这让它既快又不容易用错,也正因如此,工作量主要花在转换来自其他技术栈的密钥和签名上。
编码是算法的一部分:ECDSA_P256_SHA256_FIXED_SIGNING 生成 64 字节的原始 r‖s,ECDSA_P256_SHA256_ASN1_SIGNING 生成 DER,验证也有对应的 _FIXED 和 _ASN1 常量。用另一个常量检查签名只会报错 Unspecified,因此用 ASN1 常量验证 JWS 签名——或者用 FIXED 验证 OpenSSL 签名——看起来与伪造签名完全一样。示例展示了这两种结果。签名使用随机 nonce,s 没有经过规范化,验证时两个半区都接受。
私钥只能以 PKCS#8 DER 读取,而且 Ed25519 密钥必须是包含公钥的 PKCS#8 v2:OpenSSL 和大多数工具写出的 48 字节 v1 形式被 Ed25519KeyPair::from_pkcs8 拒绝,报错 VersionNotSupported,而 from_pkcs8_maybe_unchecked 和 from_seed_unchecked 接受了它。PEM、SEC1 和 JWK 私钥需要先转换,例如使用 JWK 转换器。公钥是裸 SEC1 点:public_key() 返回 65 字节的未压缩形式,不接受压缩点。
曲线列表只有 P-256 和 P-384,外加 Ed25519;没有 P-521,没有 secp256k1,也没有后量子算法。需要这些算法或 FIPS 认证的项目会转向 aws-lc-rs,它提供与 ring 兼容的 API。
要查看 ring 生成的签名采用哪种编码,可以把它粘贴到 DER ⇄ 原始格式转换器中。