Network Security Services 是 Firefox、Thunderbird 和多个 Linux 系统组件(包括 Firefox 的 WebCrypto)底层的库。它通过 PKCS#11 工作:密钥存放在令牌中(内置的 softoken,或者智能卡、HSM),上层的一切都调用 PK11_* 函数。本页的事实基于 Alpine 3.24.2 的软件包 NSS 3.124 检查得出,初始化时没有使用密钥数据库(NSS_NoDB_Init)。
ECDSA 有两个层,生成的编码不同。cryptohi 中的 SEC_SignData 和 VFY_VerifyData 会对消息计算哈希,并使用 DER,即 X.509、CMS 和 OpenSSL 所要求的格式。PK11_Sign 和 PK11_Verify 接收摘要,使用原始 r‖s 格式,在 P-256 上为 64 字节。混用两者是 NSS 的经典错误;可以用 DER ⇄ 原始格式转换器转换。PK11_Sign 在 P-256 上还接受了 64 字节的摘要,并对其前 32 字节签名,因此要传入与曲线匹配的摘要。
nonce 是随机的——同一条消息的两个签名不同——s 也没有经过规范化;high-S 签名能验证通过。使用 SHA-256 的 ECDSA 在 P-384 密钥上签名和验证均成功,因此哈希算法并不与曲线绑定。失败原因可以区分:VFY_VerifyData 返回 SECFailure 后,对于原始格式或被截断的签名,PORT_GetError() 报告 SEC_ERROR_BAD_DER;对于针对其他数据的有效签名,则报告 SEC_ERROR_BAD_SIGNATURE。
softoken 只能在 P-256、P-384 和 P-521 上生成密钥;P-224 和 secp256k1 报错 SEC_ERROR_INVALID_KEY。Ed25519 可以通过 CKM_EC_EDWARDS_KEY_PAIR_GEN 和 CKM_EDDSA 使用;Ed448 则不行。ML-KEM-768 封装能完成往返测试(PK11_Encapsulate、PK11_Decapsulate),而头文件中声明的 ML-DSA 机制,这个构建中的 softoken 并不提供。可以在 ML-KEM 工具中对照这个 KEM。