详解:ML-DSA 后量子签名密钥的表示、生成与导入)
网络安全认证鉴权后端【免费下载链接】joseJWA, JWS, JWE, JWT, JWK, JWKS for Node.js, Browser, Cloudflare Workers, Deno, Bun, and other Web-interoperable runtimes项目地址https://gitcode.com/gh_mirrors/jo/jose点击查看免费下载本文以 jose 仓库中 docs/types/interfaces/JWK_AKP_Public.md 文档为主体系统讲解 jose 对 AKP 类型 JSON Web KeyJWK的类型建模JWK_AKP_Public接口的每个属性含义、与 ML-DSA 后量子签名算法的绑定关系以及密钥生成、导出、导入、指纹计算等完整实战流程。读完本文你将能正确构造、校验和运用 AKP 公钥 JWK在支持 WebCrypto 的运行时上完成 ML-DSA 签名的 JWS 场景落地。一、AKP 是什么后量子签名密钥在 JWK 中的表示JWKRFC 7517通过ktyKey Type成员区分密钥类型。jose 支持EC | RSA | OKP | AKP | oct五种类型见 src/types.d.ts。其中AKP是面向ML-DSAModule-Lattice-Based Digital Signature AlgorithmNIST FIPS 204 定义的后量子数字签名算法密钥新增的类型用于承载 ML-DSA-44、ML-DSA-65、ML-DSA-87 三种参数集的公钥与私钥。从源码结构看AKP 与 ML-DSA 的绑定非常直接在 src/lib/jws_algorithms.ts 中mldsa(bits)函数将ML-DSA-44、ML-DSA-65、ML-DSA-87三个 JWS 算法标识统一映射到kty: [AKP]并以算法标识本身作为 WebCrypto 算法名源码注释明确写道“ML-DSA names its WebCrypto algorithm and its Node key type after the JWA identifier”。也就是说一个kty为AKP的 JWK其alg只会是这三个 ML-DSA 标识之一。JWK_AKP_Public就是 jose 为这种公钥 JWK 提供的 TypeScript 便利接口其定义位于 src/types.d.ts/** Convenience interface for Public AKP JSON Web Keys */ export interface JWK_AKP_Public extends JWKParameters { /** JWK alg (Algorithm) Parameter */ alg: string /** AKP JWK pub (The Public key) Parameter */ pub: string }二、JWK_AKP_Public 接口属性总览JWK_AKP_Public继承JWKParameters通用 JWK 参数集见 src/types.d.ts自身新增两个必选成员。原文档所列全部属性如下属性类型必选说明algstring是JWK algAlgorithm参数AKP 键必须显式声明算法标识pubstring是AKP JWK pubThe Public key参数Base64URL 编码的公钥ext?boolean否JWK extExtractable参数标记密钥是否可导出key_ops?string[]否JWK key_opsKey Operations参数如[verify]kid?string否JWK kidKey ID参数用于密钥标识kty?string否JWK ktyKey Type参数AKP 键建议显式填写AKPuse?string否JWK usePublic Key Use参数如sigx5c?string[]否JWK x5cX.509 Certificate Chain参数x5t?string否JWK x5tX.509 Certificate SHA-1 Thumbprint参数x5t#S256?string否JWK x5t#S256X.509 Certificate SHA-256 Thumbprint参数x5u?string否JWK x5uX.509 URL参数一个典型的 AKP 公钥 JWK 对象形如{ kty: AKP, alg: ML-DSA-65, pub: AhGV...Base64URL 编码的公钥, kid: ml-dsa-65-key-01, use: sig, key_ops: [verify] }三、必选成员alg 与 pub与 RSA/EC/OKP 通过n/e、crv/x/y等成员承载密钥材料不同AKP 键只有两个必选成员语义差异值得注意。algAlgorithmAKP 键必须携带alg。这一点在导入环节被强制校验在 src/key/import.ts 的importJWK中当kty AKP时若 JWK 上缺失或为空字符串alg会直接抛出TypeError(missing alg (Algorithm) Parameter value)。这与 RSA/EC/OKP 不同——后者允许在调用importJWK时通过第二个参数补传算法标识而 AKP 分支不仅要求alg存在还要求调用方传入的alg参数必须与 JWK 上的alg完全一致否则抛出TypeError(JWK alg and alg option value mismatch)。原因在于 ML-DSA 的 WebCrypto 算法名就是 JWA 标识本身ML-DSA-44/65/87JWK 中的alg直接决定了底层subtle.importKey使用的算法因此不允许被外部覆盖。pubThe Public key承载 Base64URL 编码的 ML-DSA 公钥本体。在 src/lib/jwk_to_key.ts 的jwkToKey中AKP 键的alg会被保留在传入crypto.subtle.importKey(jwk, ...)的keyData里if (keyData.kty ! AKP) { delete keyData.alg }其余类型的alg一律删除只有 AKP 例外——因为 WebCrypto 需要借助该alg成员确定 ML-DSA 的算法与参数集。四、继承自 JWKParameters 的可选通用参数除alg/pub外其余属性均继承自JWKParameters见 src/types.d.ts与 EC/OKP/RSA 公钥 JWK 共用同一套通用成员语义kidKey ID用于在多密钥如 JWKS场景中标识具体密钥配合 JWS 头部的kid完成密钥匹配。use建议取值sig或enc。ML-DSA 属于签名算法AKP 公钥一般标记为sig。在导入为 WebCrypto 密钥时该成员会被删除见 src/lib/jwk_to_key.ts不参与算法选择。key_ops密钥允许的操作列表。JWS 验签场景下公钥为[verify]。jwkToKey会将其作为importKey的keyUsages若未提供则回退到算法描述符的默认 usages。extExtractable 布尔值决定密钥是否可被exportKey导出。jwkToKey中默认值为!isPrivate公钥默认可导出、私钥默认不可导出。x5c/x5t/x5t#S256/x5uX.509 证书链、SHA-1/SHA-256 指纹与证书 URL用于把密钥绑定到 PKI 证书体系。AKP 键在 jose 中没有独立的 X.509 导入路径这些成员仅在 JWK 层面透传实践中 ML-DSA 密钥通常不携带它们。五、kty 参数与 AnyJWK 判别联合值得强调的是JWK_AKP_Public中的kty是可选的类型为string接口本身并不把kty锁死为AKP。这是所有JWK_*_Public/Private便利接口的共同设计它们只描述“某个类型的键需要哪些成员”便于复用JWKParameters的通用成员。若需要强制kty并借助 TypeScript 判别联合收窄类型应使用AnyJWKexport type AnyJWK | (JWK_EC_Private { kty: EC }) | (JWK_EC_Public { kty: EC }) | (JWK_RSA_Private { kty: RSA }) | (JWK_RSA_Public { kty: RSA }) | (JWK_OKP_Private { kty: OKP }) | (JWK_OKP_Public { kty: OKP }) | (JWK_AKP_Private { kty: AKP }) | (JWK_AKP_Public { kty: AKP }) | (JWK_oct { kty: oct })以上定义见 src/types.d.ts。在AnyJWK中JWK_AKP_Public与{ kty: AKP }相交从而可以在业务代码中通过if (jwk.kty AKP)收窄到 AKP 形状安全地读取pub、alg。对应文档见 docs/types/type-aliases/AnyJWK.md。六、JWK_AKP_Private从私钥到公钥的完整形状AKP 私钥由JWK_AKP_Private表示它在公钥接口基础上新增一个必选成员priv见 src/types.d.tsexport interface JWK_AKP_Private extends JWK_AKP_Public { /** AKP JWK priv (The Private Key) Parameter */ priv: string }即私钥 JWK 至少包含kty: AKP、alg、pub、priv四个成员其中priv为 Base64URL 编码的私钥种子。在 src/lib/jwk_to_key.ts 中jose 通过isPrivate !!(jwk.d || jwk.priv)判定键是否为私钥AKP 正是通过priv参与判定。对应接口文档见 docs/types/interfaces/JWK_AKP_Private.md。七、实战AKP 密钥对的生成、导出与导入jose 对 AKP 键的完整支持链路贯穿密钥生命周期均可在 Node.js、浏览器、Cloudflare Workers、Deno、Bun 等支持 WebCrypto 的运行时上使用ML-DSA 的具体可用性以运行时为准。1. 生成 ML-DSA 密钥对generateKeyPair支持ML-DSA-44 | ML-DSA-65 | ML-DSA-87见 src/key/generate_key_pair.ts。由于 ML-DSA 没有曲线概念crv选项对它无效——测试注释也明确写道“RSA and ML-DSA have no curve, so nothing is being substituted and the option stays inert”见 test/jwk/generate_key_pair.test.tsimport { generateKeyPair, exportJWK } from jose // 私钥默认不可导出如需导出 JWK 需显式打开 extractable const { publicKey, privateKey } await generateKeyPair(ML-DSA-65, { extractable: true, }) console.log(publicKey) // CryptoKey { type: public, algorithm: { name: ML-DSA-65 }, extractable: true, usages: [verify] }2. 导出为 AKP 公钥 JWKconst publicJwk await exportJWK(publicKey) console.log(publicJwk) // { kty: AKP, alg: ML-DSA-65, pub: AhGV... }导出过程有一个值得注意的细节WebCrypto 的subtle.exportKey(jwk, ...)本身不会返回alg而 jose 在 src/key/export.ts 中会先剔除ext、key_ops、alg、use再对 AKP 键把alg重新附加回去if (jwk.kty AKP) { jwk.alg alg }。这是因为 AKP 键的alg是算法标识本身缺失会破坏 JWK 的自描述性也与导入时的强校验形成闭环。注意导出要求密钥extractable true否则抛出TypeError(non-extractable CryptoKey cannot be exported as a JWK)。3. 导入 AKP JWKimport { importJWK } from jose const publicKey await importJWK(publicJwk) // 等价写法算法取自 JWK.alg // const publicKey await importJWK(publicJwk, ML-DSA-65) // 错误用法与 JWK.alg 不一致会抛错 // const wrong await importJWK(publicJwk, ML-DSA-44) // TypeError: JWK alg and alg option value mismatch如第三节所述AKP 分支要求alg必须存在于 JWK 且与调用参数一致见 src/key/import.ts底层的jwkToKey再把保留alg的 JWK 交给crypto.subtle.importKey(jwk, ...)见 src/lib/jwk_to_key.ts。4. 用于 JWS 验签导入后的公钥可直接参与compactVerify、flattenedVerify、generalVerify等 JWS 验签流程例如配合jwtVerify校验携带 ML-DSA 签名的 JWT见 docs/jws/compact/verify/functions/compactVerify.md、docs/jwt/verify/functions/jwtVerify.mdimport { jwtVerify } from jose const { payload, protectedHeader } await jwtVerify(jwt, publicKey) // protectedHeader.alg ML-DSA-65八、AKP JWK 指纹计算与本地 JWK 集匹配指纹ThumbprintcalculateJwkThumbprint对 AKP 键使用固定的成员子集{ alg, kty, pub }计算 RFC 7638 指纹——即alg和pub都是参与哈希的必选成员见 src/jwk/thumbprint.tsimport { calculateJwkThumbprint, calculateJwkThumbprintUri } from jose const thumbprint await calculateJwkThumbprint({ kty: AKP, alg: ML-DSA-44, pub: ..., }) const uri await calculateJwkThumbprintUri({ kty: AKP, alg: ML-DSA-44, pub: ..., })测试 test/jwk/thumbprint.test.ts 验证了该行为缺alg抛ERR_JWK_INVALIDalg (Algorithm) Parameter missing or invalid缺pub抛ERR_JWK_INVALIDpub (Public key) Parameter missing or invalid。指纹算法同样支持sha256 | sha384 | sha512默认sha256。对应文档见 docs/jwk/thumbprint/functions/calculateJwkThumbprint.md。本地 JWK 集createLocalJWKSet在 src/jwks/local.ts 的键匹配逻辑中有一个针对 AKP 的特殊规则——(jwkAlg undefined ? kty ! AKP : alg jwkAlg)当 JWKS 中的某个键没有声明alg时AKP 键会被排除在匹配候选之外。这再次印证了“AKP 键必须携带alg才能参与运算”的约束。对应文档见 docs/jwks/local/functions/createLocalJWKSet.md。九、使用注意事项与运行时前提综合源码实现使用 AKP 类型 JWK 时有以下关键约束alg不可缺失、不可覆盖构造 AKP JWK 时alg与pub都是必填导入时外部传入的算法标识必须与jwk.alg一致src/key/import.ts。alg只能取 ML-DSA 标识当前 jose 将 AKP 键的算法限定为ML-DSA-44、ML-DSA-65、ML-DSA-87src/lib/jws_algorithms.tsJWS 算法与 WebCrypto 算法同名。运行时支持是前提类型注释明确说明 JWS 算法标识的可用性“additionally depends on the runtime”见 src/types.d.ts。在旧版本运行时上使用 ML-DSA 可能抛出JOSENotSupported生产环境应先在目标运行时验证crypto.subtle是否支持对应算法。私钥默认不可导出generateKeyPair生成的私钥extractable默认为false需要导出私钥 JWK 时必须显式传入{ extractable: true }见 docs/key/generate_key_pair/functions/generateKeyPair.md。导出结果自动回填algexportJWK产出的 AKP JWK 会重新附加alg成员因此从 jose 导出的 AKP JWK 一定自包含算法标识src/key/export.ts。十、小结JWK_AKP_Public是 jose 为后量子签名密钥提供的第一公民支持它定义了 AKP 公钥 JWK 的完整 TypeScript 形状必选成员algML-DSA 算法标识与pubBase64URL 公钥贯穿生成、导出、导入、指纹计算与 JWKS 匹配的全链路。对开发者而言只要记住“AKP 键必须自带alg、算法不可覆盖、可用性取决于运行时”这三点就能把 ML-DSA 后量子签名平滑接入现有的 JWS/JWT 体系。相关文档与实现入口接口定义见 docs/types/interfaces/JWK_AKP_Public.md 与 src/types.d.ts算法绑定见 src/lib/jws_algorithms.ts密钥生命周期见 src/key/import.ts、src/key/export.ts、src/key/generate_key_pair.ts。赞分享网络安全认证鉴权后端【免费下载链接】joseJWA, JWS, JWE, JWT, JWK, JWKS for Node.js, Browser, Cloudflare Workers, Deno, Bun, and other Web-interoperable runtimes项目地址https://gitcode.com/gh_mirrors/jo/jose点击查看免费下载相关推荐OpenSSL 4.x ML-DSA 后量子签名实现详解FIPS 204 参数表、密钥内存布局、签名 API 与常量时间设计OpenSSL 4.x ML DSA 后量子签名实现详解FIPS 204 参数表、密钥内存布局、签名 API 与常量时间设计 本文基于 OpenSSL 仓库的密码学网络安全通信cryptography 库 ML-DSA 抗量子签名实战指南FIPS 204 密钥生成、签名与外部 mu 模式cryptography 库 ML DSA 抗量子签名实战指南FIPS 204 密钥生成、签名与外部 mu 模式 本篇指南围绕 cryptography ht密码学atproto/jwk-jose基于 jose 库的 AT Protocol JWK 密钥实现解析atproto/jwk jose基于 jose 库的 AT Protocol JWK 密钥实现解析 导读 atproto/jwk jose 是 Blues后端社交上一篇AnimatedTextInput在Jobandtalent应用中的实战应用案例分析如何打造极致用户体验的iOS输入组件下一篇go-clean-arch Kubernetes部署Helm Chart编写与集群配置创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考