Authelia 后量子密码学实战:使用 authelia crypto certificate mldsa generate 生成 ML-DSA 证书
【免费下载链接】autheliaThe Single Sign-On Multi-Factor portal for web apps. OpenID Certified™ and Post-Quantum Cryptography Ready.项目地址: https://gitcode.com/GitHub_Trending/au/authelia
Authelia 是面向 Web 应用的单点登录与多因素认证门户,并在其加密工具集中原生支持后量子密码学标准 ML-DSA(Module-Lattice Digital Signature Algorithm)。本文围绕authelia crypto certificate mldsa generate命令,完整讲解如何使用 Authelia CLI 生成 ML-DSA 私钥与 X.509 证书,涵盖全部命令行参数、参数集选择、自签名与 CA 签发两种模式、证书链捆绑输出,以及命令背后的源码实现原理,帮助你为 OIDC、TLS 等场景产出符合后量子密码学要求的证书材料。
命令定位:crypto 命令树中的 ML-DSA 分支
authelia crypto certificate mldsa generate位于 Authelia 的crypto子命令体系下。从源码结构看,crypto命令由 internal/commands/crypto.go 中的newCryptoCmd构建,挂载了rand、certificate、hash、pair四个一级子命令;其中certificate又通过newCryptoCertificateSubCmd为RSA、ECDSA、Ed25519、ML-DSA四种算法各生成一组generate(生成密钥与证书)和request(生成密钥与证书签名请求)子命令(见 internal/commands/crypto.go)。
因此完整命令层级为:
authelia crypto └── certificate ├── rsa ├── ecdsa ├── ed25519 └── mldsa ├── generate # 生成 ML-DSA 私钥与证书 └── request # 生成 ML-DSA 私钥与证书签名请求(CSR)相关命令文档:
authelia crypto certificate mldsa的概述见 authelia_crypto_certificate_mldsa.md,CSR 分支见 authelia_crypto_certificate_mldsa_request.md。
命令概述与语法
该命令的职责是“生成一个 ML-DSA 私钥和证书”(Generate an ML-DSA private key and certificate)。官方参考文档定义的基础语法如下:
authelia crypto certificate mldsa generate [flags]查看帮助信息:
authelia crypto certificate mldsa generate --help命令执行流程可从源码确认:CryptoGenerateRunE先通过cryptoGenPrivateKeyFromCmd依据--parameters生成 ML-DSA 私钥,再根据命令所属分支调用CryptoCertificateGenerateRunE完成证书模板构建、签名与文件输出(见 internal/commands/crypto.go 与 internal/commands/crypto_helper.go)。
全部选项详解(含默认值与源码依据)
以下选项来自官方参考文档,并补充了默认值来源(对应 internal/commands/crypto_helper.go 中的 flag 定义):
密钥生成选项
| 选项 | 说明 | 默认值 |
|---|---|---|
-b, --parameters string | 指定 ML-DSA 参数集,可选ML-DSA-44、ML-DSA-65、ML-DSA-87 | ML-DSA-65 |
这是 ML-DSA 分支独有的密钥参数。源码 internal/utils/crypto_mldsa.go 显示,解析参数时不仅接受完整名称(如ML-DSA-65),还接受裸安全级别(如65),且大小写不敏感;未知参数会报错,错误信息形如invalid parameters 'ML-DSA-99' were specified: parameters must be 'ML-DSA-44', 'ML-DSA-65', or 'ML-DSA-87',该行为由 internal/utils/crypto_mldsa_test.go 中的测试用例覆盖。
证书主体信息选项
| 选项 | 说明 | 默认值 |
|---|---|---|
-n, --common-name string | 证书通用名(Common Name) | 空 |
-o, --organization strings | 证书组织(Organization) | [Authelia] |
--organizational-unit strings | 证书组织单元 | 空 |
--country strings | 证书国家/地区 | 空 |
--province strings | 证书省/州 | 空 |
-l, --locality strings | 证书所在地(城市) | 空 |
-s, --street-address strings | 证书街道地址 | 空 |
-p, --postcode strings | 证书邮政编码 | 空 |
这些选项最终被组装进pkix.Name结构(见 internal/commands/crypto_helper.go),并写入证书的 Subject 字段。
有效期选项
| 选项 | 说明 | 默认值 |
|---|---|---|
--duration string | 证书有效时长 | 1y |
--not-before string | 证书生效的最早日期时间,支持多种格式 | 当前时间 |
--not-after string | 证书失效的最晚日期时间,支持多种格式 | 由--duration推导 |
源码 internal/commands/crypto_helper.go 明确了几点行为:--not-before未指定时取time.Now();--not-after与--duration不能同时指定,否则返回错误;两者都未指定时按notBefore + duration计算notAfter。--duration与时间字符串均由utils包中的解析函数处理。
主体备用名称(SAN)
| 选项 | 说明 | 默认值 |
|---|---|---|
--sans strings | 主体备用名称(Subject Alternative Names) | 空 |
SAN 支持 DNS 名称与 IP 地址混用。源码 internal/commands/crypto_helper.go 会尝试用net.ParseIP判断每个值:能解析为 IP 的放入IPAddresses,否则放入DNSNames。命令输出时以DNS.1:xxx, IP.1:1.2.3.4的形式展示(见cryptoSANsToString)。
签名与用途选项
| 选项 | 说明 | 默认值 |
|---|---|---|
--signature string | 证书签名算法 | SHA256 |
--extended-usage strings | 证书扩展用途类型 | 空 |
--ca | 将证书创建为证书颁发机构(CA)证书 | false |
需要注意:对 ML-DSA 而言,--signature选项不生效。源码 internal/commands/crypto_helper.go 的cryptoGetAlgFromCmd中,当父命令为mldsa时,签名算法直接从--parameters推导(ML-DSA-44→x509.MLDSA44,依此类推,见 internal/utils/crypto_mldsa.go),与 RSA/ECDSA/Ed25519 分支使用--signature的逻辑不同。这也符合 ML-DSA 的密码学特性——签名算法由参数集唯一确定。
--ca开启后,证书模板的IsCA置为 true,同时KeyUsage与ExtKeyUsage会依据 CA 角色自动调整(见 internal/commands/crypto_helper.go)。
输出文件与目录选项
| 选项 | 说明 | 默认值 |
|---|---|---|
-d, --directory string | 生成密钥、证书等文件的存放目录 | 空(当前目录) |
--file.private-key string | 私钥导出文件名 | private.pem |
--file.certificate string | 证书导出文件名 | public.crt |
--file.ca-private-key string | 用于签名的 CA 私钥文件名 | ca.private.pem |
--file.ca-certificate string | 用于签名的 CA 证书文件名 | ca.public.crt |
--file.bundle.chain string | --bundles含chain时证书链 PEM 捆绑包文件名 | public.chain.pem |
--file.bundle.priv-chain string | --bundles含priv-chain时证书链+私钥 PEM 捆绑包文件名 | private.chain.pem |
--bundles strings | 启用捆绑包生成,取值chain与priv-chain | 空 |
--legacy | 启用旧版 PKCS#1 与 SECG1 格式输出 | false |
--file.extension.legacy string | 旧版格式中位于实际扩展名之前的子扩展名 | legacy |
--path.ca string | CA 文件源目录;不提供则生成自签名证书 | 空 |
关于输出路径,源码cryptoGetWritePathsFromCmd(见 internal/commands/crypto_helper.go)定义了文件名选择的规则:若指定了--ca,私钥写为--file.ca-private-key(默认ca.private.pem)、证书写为--file.ca-certificate(默认ca.public.crt);普通证书则写为--file.private-key与--file.certificate。所有路径都会与--directory拼接。
关于--legacy:PKCS#1 / SECG1 是 RSA 与 ECDSA 密钥的传统编码格式,而ML-DSA 密钥并不存在这两种旧格式。源码cryptoKeyProperties对 ML-DSA 返回的legacy标志为false(见 internal/commands/crypto_helper.go),因此--legacy对 ML-DSA 实际不产生额外输出,该选项主要是与 RSA/ECDSA 子命令保持 CLI 一致性。
通用(继承)选项
| 选项 | 说明 | 默认值 |
|---|---|---|
-c, --config strings | 要加载的配置文件或目录 | [configuration.yml] |
--config.experimental.filters strings | 应用于所有配置文件的过滤器列表 | 空 |
-h, --help | 显示命令帮助 | — |
ML-DSA 参数集与构建前提
ML-DSA 是 NIST 标准化的后量子签名算法,按安全强度分为三个参数集:
| 参数集 | 完整名称 | 签名算法标识 |
|---|---|---|
ML-DSA-44 | Module-Lattice Digital Signature Algorithm 44 | x509.MLDSA44 |
ML-DSA-65(默认) | 同上,强度 65 | x509.MLDSA65 |
ML-DSA-87 | 同上,强度 87 | x509.MLDSA87 |
常量定义见 internal/utils/const.go。
重要的构建前提:Authelia 的 ML-DSA 支持依赖 Go 标准库crypto/mldsa,该包在Go 1.27中才正式落地。源码 internal/utils/crypto_mldsa.go 与 internal/oidc/mldsa.go 均明确注明:使用更早工具链构建的 Authelia 二进制不支持任何 ML-DSA 操作,此时GenerateMLDSAKey会返回错误“generating ML-DSA private keys requires this binary to be built with Go 1.27 or later”(见 internal/utils/crypto_mldsa_stub.go)。因此在使用本命令前,请确认你的 Authelia 二进制由 Go 1.27 或更高版本构建。
ML-DSA 密钥生成还有一个实现细节:不同于 RSA/ECDSA/Ed25519 通过ctx.providers.Random注入随机源,crypto/mldsa自身从crypto/rand取随机种子且不提供外部注入接口,因此GenerateMLDSAKey不接收随机源参数(见 internal/utils/crypto_mldsa.go)。
实战场景一:生成自签名 ML-DSA 证书
最基本的用法是不提供--path.ca,此时证书为自签名(源码中cryptoGetCAFromCmd在未指定--path.ca时返回 nil,随后parent = template实现自签名,见 internal/commands/crypto.go):
authelia crypto certificate mldsa generate \ --directory ./certs \ --common-name authelia.example.com \ --sans authelia.example.com,192.168.1.10 \ --duration 2y该命令将在./certs目录下生成private.pem(ML-DSA-65 私钥)与public.crt(自签名证书)。由于 ML-DSA 的签名算法由参数集决定,命令输出中的Signature Algorithm会自动显示为对应参数集(如MLDSA65),无需也无法通过--signature覆盖。
实战场景二:使用已有 CA 签发 ML-DSA 证书
企业内网或生产环境中通常希望由受信任的 CA 签发证书。首先用--ca生成一个 CA 证书:
authelia crypto certificate mldsa generate \ --directory ./ca \ --common-name "Authelia Internal CA" \ --ca \ --duration 10y \ --parameters ML-DSA-87输出./ca/ca.private.pem与./ca/ca.public.crt(文件名由--file.ca-private-key/--file.ca-certificate的默认值决定)。
然后通过--path.ca指向 CA 目录,为实际域名签发:
authelia crypto certificate mldsa generate \ --directory ./certs \ --common-name portal.example.com \ --sans portal.example.com \ --path.ca ./ca \ --duration 1y此时命令会读取./ca/ca.private.pem与./ca/ca.public.crt(源码 internal/commands/crypto_helper.go 中cryptoGetCAFromCmd负责读取与解析),并用 CA 私钥对新证书签名(signatureKey = caPrivateKey,见 internal/commands/crypto.go)。命令输出会显示签发方信息:Signed By: <CA Common Name>以及 CA 的序列号与过期时间。
实战场景三:生成证书链与私钥捆绑包
使用--bundles可以额外输出 PEM 捆绑包:
authelia crypto certificate mldsa generate \ --directory ./certs \ --common-name portal.example.com \ --path.ca ./ca \ --bundles chain,priv-chainchain:生成public.chain.pem,内容为“证书 + CA 证书”的 PEM 链(默认文件名见--file.bundle.chain);priv-chain:生成private.chain.pem,内容为“私钥 + 证书 + CA 证书”(默认文件名见--file.bundle.priv-chain)。
捆绑逻辑由 internal/commands/crypto_helper.go 的cryptoGenerateCertificateBundlesFromCmd实现:chain把证书与 CA 证书依次写入 PEM 块;priv-chain则将私钥 PEM 块置于链首。若未指定--path.ca(自签名),捆绑包中自然不包含 CA 证书块。
命令输出解读
执行生成时,命令会在 stdout 打印一段结构化摘要(见 internal/commands/crypto.go 的CryptoCertificateGenerateRunE),包含:
- 证书序列号(128 位随机数,来源见 internal/commands/crypto_helper.go);
- 签发方式(
Self-Signed或 CA 的 Common Name、序列号与过期时间); - Subject 信息(Common Name、Organization、Organizational Unit、Country、Province、Street Address、Postal Code、Locality);
- 属性(Not Before / Not After、CA 标志、Signature Algorithm、Public Key Algorithm、ML-DSA 参数集、SAN 列表);
- 输出路径(目录、私钥文件、证书文件、可选捆绑包文件)。
例如(示意):
Generating Certificate Serial: 7f3a… Signed By: Authelia Internal CA Serial: 9b2c…, Expires: 2036-… Subject: Common Name: portal.example.com, Organization: [Authelia], … Properties: Not Before: …, Not After: … CA: false, CSR: false, Signature Algorithm: MLDSA65, Public Key Algorithm: MLDSA, Parameters: ML-DSA-65 Subject Alternative Names: DNS.1:portal.example.com Output Paths: Directory: certs Private Key: private.pem Certificate: public.crt与 OIDC 后量子签名的联动
本命令生成的 ML-DSA 密钥并不仅限于 TLS 证书场景,Authelia 的 OIDC 授权服务器同样支持 ML-DSA 签名。源码 internal/oidc/mldsa.go 定义了SigningAlgsMLDSA,按参数集升序暴露ML-DSA-44、ML-DSA-65、ML-DSA-87三种 JWS 签名算法,并要求同样的 Go 1.27 构建前提;SigningAlgFromMLDSAKey则根据密钥所属参数集返回对应的 JWSalg值(见 internal/oidc/mldsa.go)。这也解释了为什么项目将自身定位为“OpenID Certified™ and Post-Quantum Cryptography Ready”——ML-DSA 的 CLI 支持与 OIDC 签名支持共享同一套后量子密钥基础设施。
常见错误与排查
invalid parameters 'xxx' were specified: parameters must be 'ML-DSA-44', 'ML-DSA-65', or 'ML-DSA-87':--parameters取值非法。接受完整名称或裸级别数字(如44、65、87),大小写不敏感。generating ML-DSA private keys requires this binary to be built with Go 1.27 or later:当前二进制由 Go 1.27 之前的工具链构建,不具备 ML-DSA 能力,请更换为支持crypto/mldsa的构建。failed to determine not after:同时指定了--not-after与--duration,二者互斥,只保留其一。- CA 文件读取失败:
--path.ca指定的目录下必须存在ca.private.pem与ca.public.crt(或通过--file.ca-private-key/--file.ca-certificate覆盖文件名),且内容必须是合法的 PEM 私钥与证书。
参考文档与源码索引
- 命令参考文档:authelia_crypto_certificate_mldsa_generate.md
- 父命令文档:authelia_crypto_certificate_mldsa.md
- 命令实现:internal/commands/crypto.go、internal/commands/crypto_helper.go
- ML-DSA 密钥工具:internal/utils/crypto_mldsa.go、internal/utils/crypto_mldsa_stub.go、internal/utils/crypto_mldsa_test.go
- OIDC ML-DSA 签名算法:internal/oidc/mldsa.go
综上,authelia crypto certificate mldsa generate是 Authelia 后量子密码学能力的直接入口:一条命令即可完成 ML-DSA 私钥生成、证书构建、自签名或 CA 签发、SAN 注入、有效期控制与证书链捆绑,且默认参数集ML-DSA-65兼顾了安全强度与兼容性。配合 OIDC 侧的 ML-DSA 签名支持,Authelia 为追求后量子安全的应用提供了从密钥生成到身份签名认证的完整闭环。
【免费下载链接】autheliaThe Single Sign-On Multi-Factor portal for web apps. OpenID Certified™ and Post-Quantum Cryptography Ready.项目地址: https://gitcode.com/GitHub_Trending/au/authelia
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考