1. 引言
本文描述了在 Web Authentication (WebAuthn) 中实现无密码认证(Passwordless authentication)的方法,该方法使用模块格(Module-Lattice)为基础的数字签名标准(ML-DSA),即 FIPS 204 定义的后量子密码学(PQC)数字签名方案。
本文描述了如何将 [FIPS-204] 中描述的 ML-DSA 密钥和签名应用于 [WebAuthn]。
2. 后量子密码学背景
本节描述了后量子密码学(Post-Quantum Cryptography)、Web 认证(Web Authentication)及防钓鱼机制(Phishing Resistance)的通用背景。后量子密码学被定义为一组不易受到拥有大规模量子计算机的恶意攻击者威胁的密码算法。[FIPS-204] 描述了一种基于模块格(Module-Lattice)的数字签名算法,该算法不易受到涉及大规模量子计算机的攻击。
2.1 在 WebAuthn 中使用 ML-DSA 的动机
随着防钓鱼的无密码认证标准(如安全密钥(Security Keys)、通行密钥(Passkeys)和设备证明(Device attestation))根据 FIDO2 规范得到广泛采用,用于认证的密码标准主要为 ES256(椭圆曲线数字签名算法与 SHA-256 组合)和 RS256(RSA 与 SHA-256 组合),这些标准定义于 [FIPS-186-5]。尽管大多数认证器也支持其他算法,但被广泛使用的默认算法——ES256 和 RS256——被认为在面对使用大规模量子计算机的对手时是不安全的。
因此,在 WebAuthn 中采用 ML-DSA 对于保护数字身份和账户免受此类对手的攻击是必要的。
3. ML-DSA 在 WebAuthn 中的集成
本节描述了基于 ML-DSA 的 WebAuthn 实现。
3.1 COSE 中的 ML-DSA 密钥表示
[I-D.draft-ietf-cose-dilithium-05] 描述了用于 ML-DSA 的 CBOR 对象签名与加密(COSE,CBOR Object Signing and Encryption)序列化。需要注意的是,WebAuthn 中仅使用 “公钥” 或 “验证密钥” 的 COSE 表示。因此,私钥的 COSE 表示超出了本文讨论范围。
ML-DSA 签名方案通过参数化支持不同的安全级别。本文使用 ML-DSA-44、ML-DSA-65 和 ML-DSA-87 的缩写,分别表示 FIPS-204 表 1 中给出的不同参数选择下的 ML-DSA。
结合 [I-D.draft-ietf-cose-dilithium-05],本文请求在 [IANA.cose] 中注册以下算法:
名称 | 值 | 描述 |
---|---|---|
ML-DSA-44 | TBD(请求分配 -48) | ML-DSA-44 的 CBOR 对象签名算法 |
ML-DSA-65 | TBD(请求分配 -49) | ML-DSA-65 的 CBOR 对象签名算法 |
ML-DSA-87 | TBD(请求分配 -50) | ML-DSA-87 的 CBOR 对象签名算法 |
根据 [I-D.draft-ietf-cose-dilithium-05] 中算法密钥对类型(Algorithm Key Paid Type)部分的说明,当出现在 AKP 密钥中时,“pub” 参数具有以下约束:
- “pub” 参数是 ML-DSA 公钥,如 FIPS-204 第 5.3 节所述。
这些算法的 “pub” 大小以及相关的签名大小在 FIPS-204 表 2 中定义,为方便起见,这里再次列出:
算法 | 私钥大小(字节) | 公钥大小(字节) | 签名大小(字节) |
---|---|---|---|
ML-DSA-44 | 2560 | 1312 | 2420 |
ML-DSA-65 | 4032 | 1952 | 3309 |
ML-DSA-87 | 4896 | 2592 | 4627 |
这些算法用于生成符合 FIPS-204 算法 2 描述的签名。
签名使用 FIPS-204 第 7.2 节定义的算法编码为字节串。
3.2 签名生成与验证
签名生成依据 FIPS-204 第 5.2 节执行,签名验证依据 FIPS-204 第 5.3 节执行。
如果需要较小的密钥或签名,ML-DSA 可能并非理想选择。此外,在期望更快处理速度的使用场景下,ML-DSA-87 可能并非最佳选项。因此,建议在 WebAuthn 中使用 ML-DSA-44 和 ML-DSA-65。
4. 认证器行为
本节描述认证器(无论是漫游认证器还是平台认证器)如何实现 ML-DSA。
认证器 必须 具有安全存储,用于存储加密机密,并且 不应 以未授权的方式导出这些机密。
4.1 凭证创建
+---------------+ +--------+ +-----------+| | | | | || Authenticator | | Client | | RP Server || | | | | |+-------+-------+ +---+----+ +-----+-----+| | || | || | || | || | Get Challenge || +--------------------------------------------->|| | || | || | || | Challenge || |<---------------------------------------------+| | || | || | || | || | || | || | || | || | || Credential Creation Request | ||<-------------------------------+ |
+----------------+ (Challenge) | |
| Generate | | |
| Keypair | | |
| | | |
| | | |
| | | |
+--------------->| | || | |
+----------------+ | |
| Sign challenge | | |
| | | |
| | | |
| | | |
| | | |
+--------------->| | || | || Assertion Response | |+------------------------------->| || (Signed Challenge) | Assertion || +--------------------------------------------->|| | || | +--------------------+| | | Verify || | | || | | || | | || | | || | |<-------------------+| | || | +--------------------+| | | Save public key || | | || | | || | | || | | || | | || | |<-------------------+| | Authentication response || |<---------------------------------------------+| | || | || | || | || | || | || | |
[WebAuthn] 定义了凭证创建 API。该 API 接收一个公钥凭证创建对象,其中包含加密挑战、依赖方 ID(RP ID,Relying Party ID)、用户信息以及公钥凭证参数。公钥凭证参数定义了可接受的算法。
一个公钥凭证创建对象的示例如下:
{ challenge: new Uint8Array([215, 150, 119, 213, 215, 247, 188, 15, 142, 10, 53, 135, 17, 205, 130, 133, 158, 32, 113, 0, 62, 67, 112, 191, 123, 180, 224, 151, 233, 114, 68, 225]), rp: { id: "example.com", name: "Example Corporation" }, user: { id: new Uint8Array([79, 252, 83, 72, 214, 7, 89, 26]), name: "johndoe", displayName: "John Doe", }, pubKeyCredParams: [{ type: "public-key", alg: -7 }, { type: "public-key", alg: -49 }],
}
Web 应用通过调用 Navigator.credentials.create()
函数并传入公钥凭证创建对象来发起凭证创建。客户端 Web 浏览器或应用程序调用 KaTeX parse error: Expected 'EOF', got '#' at position 75: …ebauthn-00.html#̲CTAP) 定义的认证器 API。
公钥凭证创建对象会被 CBOR 编码,并通过选定的传输方式(包括但不限于 USB HID、BLE 和 NFC)发送到认证器设备。
公钥凭证创建对象的 CBOR 编码示例如下:
h'A50158201637B26333915747DBDC6C630C0165405A64939AE8F6E4FC39414F853F702F1602A2626964696C6F63616C686F7374646E616D656B44656D6F2073657276657203A3626964504EC1D4219F294FB4A0BC0CD29D485AFC646E616D6566615F757365726B646973706C61794E616D6567412E20557365720481A263616C67382F64747970656A7075626C69632D6B657907A1627576F5'
认证器 必须 验证公钥凭证创建对象中 "excludeCredentials"
列表中提到的任何凭证是否已存在于认证器上。若已存在,则认证器应根据 [CTAP] 返回错误代码。
此外,认证器 必须 执行涉及认证器 PIN、用户存在性(User Presence)、用户验证(User Verification)等的所有附加检查,符合 CTAP 第 5.1 节的规定。
当公钥凭证参数中包含 alg -49
或 alg -48
时,认证器 应 分别使用 ML-DSA-65 或 ML-DSA-44 算法。
如果参数不存在,认证器 应 按照本文“向后兼容性考虑”部分的规定执行。
认证器根据 FIPS 204 第 5.1 节生成 ML-DSA 密钥对及唯一的 Key ID。公钥按照 [I-D.draft-ietf-cose-dilithium-05] 进行 COSE 编码,并作为 attestedCredentialData
的一部分。
在按照 CTAP 第 5.1 节通过所有检查后,认证器 应 生成认证声明(attestation statement)。
authData
按照 WebAuthn 和 CTAP 规范创建,并附加 clientDataHash
。然后使用生成的密钥对的私钥对其进行签名。
认证声明按照 CTAP 和 WebAuthn 生成。
ML-DSA 私钥必须根据本文档的“存储安全和密钥管理”部分进行存储。
认证声明采用 CBOR 编码,并通过相同的传输方式返回给客户端应用程序。
4.2 认证流程
+---------------+ +--------+ +-----------+| | | | | || Authenticator | | Client | | RP Server || | | | | |+-------+-------+ +---+----+ +-----+-----+| | || | || | || | || | Get Challenge || +--------------------------------------------->|| | || | || | || | Challenge || |<---------------------------------------------+| | || | || | || | || | || | || | || | || | || Assertion Request | ||<-------------------------------+ || (Challenge) | |
+-------------+ | |
|Sign | | |
|Challenge | | |
| | | |
| | | |
+------------>| | || Assertion Response | |+------------------------------->| || (Signed Challenge) | || | || | || | || | || | || | || | || | || | Assertion || +--------------------------------------------->|| | || | +--------------------+| | | Verify || | | || | | || | | || | | || | |<-------------------+| | Authentication response || |<---------------------------------------------+| | || | || | || | || | || | || | || | || | || | || | || | || | || | || | || | || | || | |
[WebAuthn] 定义了凭证请求 API。该 API 接收一个公钥凭证请求对象,其中包含加密挑战(cryptographic challenge)、依赖方 ID(RP ID),以及可选的允许凭证列表。
公钥凭证请求对象示例如下:
{challenge: new Uint8Array([215, 150, 119, 213, 215, 247, 188, 15, 142, 10, 53, 135, 17, 205, 130, 133, 158, 32, 113, 0, 62, 67, 112, 191, 123, 180, 224, 151, 233, 114, 68, 225]),rpId: "example.com",
}
Web 应用通过 Navigator.credentials.get()
函数调用该公钥凭证请求对象。
客户端 Web 浏览器或应用程序调用 KaTeX parse error: Expected 'EOF', got '#' at position 75: …ebauthn-00.html#̲CTAP) 中定义的认证器 API。
公钥凭证请求对象会进行 CBOR 编码,并通过所选的传输方式(包括但不限于 USB HID、BLE 和 NFC)发送至认证器设备。
如果提供了 allowedCredentials
列表,认证器 必须 查找绑定至相同 RP ID 的凭证,该凭证必须存在于列表中。若不存在此类凭证,认证器应根据 KaTeX parse error: Expected 'EOF', got '#' at position 75: …ebauthn-00.html#̲CTAP) 返回错误代码。
此外,认证器 必须 执行涉及认证器 PIN、用户存在性(User Presence)、用户验证(User Verification)等的所有附加检查,符合 CTAP 第 5.2 节的规定。
认证器在找到合适的凭证后 应 验证其算法。
如果算法不是 ML-DSA,认证器 必须 按照本文档“向后兼容性考虑”部分的规定执行。
凭证的检索须符合本文档“存储安全与密钥管理”部分的要求。
在通过 CTAP 第 5.2 节的所有检查后,认证器 应 创建断言(assertion)声明。
authData
按照 WebAuthn 和 CTAP 规范创建,并将 clientDataHash
附加其后。
该数据使用解密后的 ML-DSA 私钥签名。
断言响应(assertion response)按 CTAP 和 WebAuthn 规范生成。
断言响应使用 CBOR 编码,并通过相同的传输方式返回给客户端应用。
所有用于处理 ML-DSA 私钥的内存地址必须立即清零(zeroized)。
authenticator getNextAssertion()
函数的规范应根据 [CTAP] 进行类似实现。
4.3 向后兼容性考虑
如果依赖方(RP)不支持 ML-DSA,认证器 应 默认使用符合 FIPS-186-5 的 RS256 和 ES256 算法,
可通过检查凭证创建过程中公共密钥凭证参数字段(Public Key Credential Parameters)来验证。
5. 客户端与平台考虑
本节描述客户端和平台的相关注意事项。
5.1 WebAuthn 客户端中的 COSE 算法支持
客户端的 CTAP 实现(如 Microsoft Windows 系统的 Windows Hello、Apple 系统的 iCloud 钥匙串、Google Password Manager、Dashlane、OnePassword 以及其他基于浏览器的 Linux 实现) 应 根据 COSE 支持 ML-DSA 算法。
此外,推荐这些设备的平台认证器支持 ML-DSA 密钥生成和签名,符合本文档要求。
5.2 处理大尺寸签名和密钥
已考虑所选的传输方式(包括但不限于 USB HID、BLE 和 NFC)能够传输 CBOR 编码的数据,这些数据往往超过 2000 字节。
使用证明证书(attestation certificates)可能会进一步增加长度。
5.3 错误处理与回退机制
在涉及 ML-DSA 密钥生成和签名的错误情况下,认证器可以回退使用 ES256 或 RS256 算法。
在涉及与客户端通信的错误情况下,认证器可根据 [CTAP] 进行处理。
6. 安全性考虑
[RFC9053] 的安全性考虑同样适用于本规范。
ML-DSA 的详细安全性分析超出本文范畴,更多细节参见 [FIPS-204]。
6.1 抗量子攻击能力
有关抗量子攻击能力的详细信息,参见 [FIPS-204]。
6.2 存储安全与密钥管理
需要注意的是,在撰写本文时,还没有适用于 ML-DSA 的合适的硬件安全模块(HSM)、可信平台模块(TPM)、安全元件(SE)或可信执行环境(TEE)能够原生支持 ML-DSA。
因此,安全凭证存储是一个挑战。
为了解决这一问题,ML-DSA 密钥(也称凭证)必须使用高级加密标准(AES)进行加密,AES 是一种抗量子的对称加密算法,采用 Galois/Counter 模式(GCM)并使用 256 位密钥。
AES 密钥必须在安全存储中生成和存储,该存储可包括 HSM、TPM、SE 或 TEE。
ML-DSA 密钥可以在标准计算环境(安全存储之外)生成,但在写入闪存或磁盘之前,必须使用上述 AES 加密进行加密。
相反,在使用前,必须在安全存储中使用 AES 对其进行解密。
任何用于处理 ML-DSA 凭证的内存位置、指针或堆内存,在操作完成后必须立即清零。
当支持 ML-DSA 的安全存储模块广泛可用时,本节将进行更新。
7.3 实现最佳实践
如果安全存储空间允许,建议每个 ML-DSA 私钥使用唯一的 AES 密钥加密:
- 存储前,每个 ML-DSA 私钥都应独立使用不同的 AES 加密密钥进行加密。
- 为确保强大的加密能力,AES 密钥大小必须至少为 AES-256。
- 为防止未经授权的访问,加密密钥应保存在硬件安全模块(HSM)、安全元件(SE)或可信平台模块(TPM)中。
- 密钥管理应遵循 NIST SP 800-57 的建议,以提供安全的 AES 密钥生命周期管理(创建、存储、轮换和销毁)。
- 私钥仅应在可信执行环境(TEE)或安全隔离区中解密,以避免内存泄漏。
7. IANA 注意事项
7.1 现有注册表的新增条目
结合 [I-D.draft-ietf-cose-dilithium-05],
本文请求向 COSE 算法注册表中注册以下条目。
以下填写完成的注册模板根据 RFC9053 和 RFC9054 的说明提供。
7.1.1 待添加的算法
7.1.1.1 ML-DSA-44
- 名称:ML-DSA-44
- 数值:待定(请求分配为 -48)
- 描述:ML-DSA-44 的 CBOR 对象签名算法
- 能力:[kty]
- 参考文献:RFC XXXX
- 推荐使用:是
7.1.1.2 ML-DSA-65
- 名称:ML-DSA-65
- 数值:待定(请求分配为 -49)
- 描述:ML-DSA-65 的 CBOR 对象签名算法
- 能力:[kty]
- 参考文献:RFC XXXX
- 推荐使用:是
7.1.1.3 ML-DSA-87
- 名称:ML-DSA-87
- 数值:待定(请求分配为 -50)
- 描述:ML-DSA-87 的 CBOR 对象签名算法
- 能力:[kty]
- 参考文献:RFC XXXX
- 推荐使用:是
7.1.2 新的 COSE 密钥类型
请求 IANA 将以下条目添加到 COSE 密钥类型注册表中。以下为根据 RFC9053 提供的完整注册模板。
7.1.2.1 AKP
- 名称:AKP
- 数值:待定(请求分配为 7)
- 描述:用于算法密钥对的 COSE 密钥类型
- 能力:[kty(7)]
- 参考文献:RFC XXXX
7.1.3 新的 COSE 密钥类型参数
请求 IANA 将以下条目添加到 COSE 密钥类型参数中。以下为根据 RFC9053 提供的完整注册模板。
7.1.3.1 ML-DSA 公钥
- 密钥类型:待定(请求分配为 7)
- 名称:pub
- 标签:-1
- CBOR 类型:bstr
- 描述:公钥
- 参考文献:RFC XXXX
参考资料
[1] 2025年4月 ML-DSA for Web Authentication