AgariusMeredius/ml-pki

GitHub: AgariusMeredius/ml-pki

一个基于 ML-DSA 与 CBOR 的后量子 PKI 库,提供密钥生成、证书签发与吊销的原生支持。

Stars: 0 | Forks: 0

# mlpki Python 的后量子公钥基础设施库。 `mlpki` 使用 **ML-DSA**(FIPS 204 / CRYSTALS-Dilithium)通过 [liboqs](https://github.com/open-quantum-safe/liboqs) 实现证书管理和数字签名。 所有数据结构均以 **CBOR** 格式序列化,使用整数密钥 —— 无 ASN.1、无 TLS、无密钥交换。该库涵盖完整的 PKI 生命周期:密钥生成、证书签发、CSR 工作流、链验证和吊销。 ## 功能特性 - **ML-DSA-44 / 65 / 87** — 全部三种 NIST 后量子安全等级 - **CBOR 序列化**,使用整数密钥和 Unix 时间戳 - **双层证书格式** — TBS 字节单独签名,外层结构携带 `tbs_bytes + sig_alg + signature` - **证书签名请求(CSR)**,带自签名以证明密钥拥有权 - **完整链验证** — 签名、有效期窗口、CA 标志、 `KEY_CERT_SIGN`、`path_len` 约束、权威密钥标识符匹配、 吊销状态 - **证书吊销列表(CRL)** — 仅追加不可变、CBOR 序列化、 ML-DSA 签名 - **加密密钥存储** — Argon2id 密钥派生 + AES-256-GCM, CBOR 文件格式 - **类似 PEM 的导出** 用于证书和 CSR(`-----BEGIN ML-CERTIFICATE-----`) ## 要求 - Python ≥ 3.11 - [liboqs](https://github.com/open-quantum-safe/liboqs) 共享库(≥ 0.14) - `liboqs-python`、`cbor2`、`argon2-cffi`、`cryptography` ## 安装 ``` # 1. Build and install liboqs (shared library) git clone --depth 1 --branch 0.14.0 https://github.com/open-quantum-safe/liboqs.git cmake -S liboqs -B liboqs/build -GNinja \ -DCMAKE_BUILD_TYPE=Release \ -DBUILD_SHARED_LIBS=ON \ -DOQS_BUILD_ONLY_LIB=ON cmake --build liboqs/build sudo cmake --install liboqs/build # 2. Install Python dependencies pip install liboqs-python cbor2 argon2-cffi "cryptography>=42" # 3. Install mlpki (editable) pip install -e . ``` ## 快速开始 ### 1 — 创建根 CA ``` from mlpki import create_root_ca, Name, ALG_ML_DSA_65, save_secret_key root_cert, root_sec = create_root_ca( subject=Name(cn="My Root CA", org="My Organisation"), validity_days=3650, alg=ALG_ML_DSA_65, ) save_secret_key("root_ca.mlkey", root_sec, ALG_ML_DSA_65, b"strong-password") with open("root_ca.pem", "w") as f: f.write(root_cert.to_pem()) ``` ### 2 — 签发证书 ``` from mlpki import ( Certificate, generate_keypair, issue_certificate, load_secret_key, verify_chain, KEY_USAGE_DIGITAL_SIGNATURE, ) root_cert = Certificate.from_pem(open("root_ca.pem").read()) root_sec, root_alg = load_secret_key("root_ca.mlkey", b"strong-password") ee_pub, ee_sec = generate_keypair(root_alg) ee_cert = issue_certificate( subject=Name(cn="service.example.com", org="My Organisation"), subject_pub=ee_pub, issuer_cert=root_cert, issuer_sec=root_sec, validity_days=365, key_usage=KEY_USAGE_DIGITAL_SIGNATURE, ) verify_chain([ee_cert], trusted_root=root_cert) # raises on failure ``` ### 3 — CSR 工作流 ``` from mlpki import ( CertificateSigningRequest, generate_keypair, issue_from_csr, verify_chain, Name, ALG_ML_DSA_44, ) # --- Applicant --- pub, sec = generate_keypair(ALG_ML_DSA_44) csr = CertificateSigningRequest.create( subject=Name(cn="applicant.example.com", org="Applicant Org"), pub=pub, sec=sec, alg=ALG_ML_DSA_44, ) csr_pem = csr.to_pem() # transmit to CA # --- CA --- csr = CertificateSigningRequest.from_pem(csr_pem) assert csr.verify_self_signature() cert = issue_from_csr(csr, issuer_cert=root_cert, issuer_sec=root_sec) ``` ### 4 — 吊销 ``` from mlpki import RevocationList crl = RevocationList.create(root_cert, root_sec, next_update_days=30) crl = crl.add_serial(ee_cert.tbs.serial, root_cert, root_sec) from mlpki.verify import VerificationError try: verify_chain([ee_cert], trusted_root=root_cert, crl=crl) except VerificationError as e: print(e.code) # VerificationCode.REVOKED ``` ### 5 — 签名与验证数据 ``` from mlpki import generate_keypair, sign, ALG_ML_DSA_65 from mlpki.keys import verify pub, sec = generate_keypair(ALG_ML_DSA_65) sig = sign(b"my message", sec, ALG_ML_DSA_65) ok = verify(b"my message", sig, pub, ALG_ML_DSA_65) ``` ## 项目结构 ``` mlpki/ ├── __init__.py Public API re-exports ├── constants.py Field numbers, algorithm IDs, key-usage flags ├── certificate.py Name, PublicKeyInfo, TBSCertificate, Certificate ├── keys.py Key generation, sign, verify, encrypted storage ├── csr.py CertificateSigningRequest ├── ca.py CA operations (create_root_ca, issue_certificate …) ├── revocation.py RevocationList (CRL) └── verify.py verify_chain, verify_signature, VerificationError tests/ pytest suite — 144 tests, no network required examples/ Runnable end-to-end scripts docs/ Architecture, API reference, format spec, security ``` ## 运行测试 ``` pytest tests/ -q ``` ## 文档 详细文档位于 [`docs/`](docs/): | 文件 | 内容 | |---|---| | [`architecture.md`](docs/architecture.md) | 模块概览、数据流、设计决策 | | [`api-reference.md`](docs/api-reference.md) | 每个公共函数的完整 API 参考 | | [`formats.md`](docs/formats.md) | CBOR 序列化格式规范 | | [`security.md`](docs/security.md) | 安全注意事项与威胁模型 | ## 使用警告与安全注意事项 ### 算法选择 | 变体 | NIST 等级 | 推荐用途 | |---|---|---| | `ALG_ML_DSA_44` | 2(128 位经典) | **仅限开发与测试** | | `ALG_ML_DSA_65` | 3(192 位经典) | 通用生产使用 | | `ALG_ML_DSA_87` | 5(256 位经典) | 高安全或长寿命证书(> 10 年) | **不要在生产环境中使用 `ALG_ML_DSA_44`。** 其 128 位经典安全等级是 NIST 接受的最低级别,仅为测试和受限设备提供速度优势。 ### 密钥管理 - 使用 `save_secret_key()` 并搭配 **强随机生成的密码**(≥ 32 字节,来自 `secrets.token_bytes()`)。人类可记忆的密码短语不足以保护根 CA 密钥。 - 限制密钥文件权限:`chmod 600 root_ca.mlkey` - 在不进行签名时,将根 CA 密钥文件存储在 **离线或硬件安全介质** 上。 - 密钥字节为纯 Python `bytes` 对象 —— Python 在垃圾回收时不会清零内存。请将密钥保持在局部作用域;不要将其缓存在全局状态中。 ### CRL 新鲜性 `verify_chain()` 现在 **强制** 要求提供的 CRL 的 `next_update` 时间戳在未来。旧的 CRL 将引发 `VerificationError`,错误代码为 `CRL_EXPIRED`。应用程序必须在过期前刷新 CRL: ``` # Refresh before next_update; never let CRLs go stale. crl = RevocationList.create(issuer_cert, issuer_sec, next_update_days=7) ``` ### 链深度 `verify_chain()` 拒绝超过 `max_depth`(默认:10)的链。为扁平 PKI 层次结构设置更严格的限制以减少攻击面: ``` verify_chain([ee_cert], trusted_root=root_cert, max_depth=2) ``` ### CSR 处理 `issue_from_csr()` 会自动验证 CSR 自签名。但 CA 仍必须独立应用其自身的 **签发策略** —— 例如,是否接受 CSR 的 `is_ca=True` 请求。该库将 CSR 主题中的请求扩展传输到签发者约束;它不会强制命名策略或组织验证。 ### `mlpki` 不提供的内容 - **无密钥交换或机密性** — ML-DSA 仅是签名方案;无 KEM、无 TLS、无加密通道 - **无 OCSP** — 仅通过批处理 CRL 吊销;无实时吊销状态 - **无 X.509 / TLS 兼容性** — 证书使用自定义 CBOR 格式,与现有 X.509 基础设施不兼容 - **无名称约束** — CA 无法限制子 CA 的主题命名空间 - **无时钟偏差容忍** — 有效期检查使用精确整数比较;即使 1 秒的 NTP 漂移也可能导致新签发证书出现 `NOT_YET_VALID` ### 安全审计 于 2026-04-13 完成了完整的安全与功能审计。 请参阅 [`AUDIT.md`](AUDIT.md) 获取所有发现、已应用的修复以及剩余可接受的风险。 ## 免责声明 `mlpki` 是一个**实验性研究库**,实现了基于 ML-DSA(FIPS 204)的后量子 PKI 原语。 本库以教育目的、原型设计和后量子证书基础设施评估为目的提供。 **本项目由 Claude Sonnet 4.6 与 Claude Code(Sonnet 4.6)开发、调试和审计。** 完整的代码库(包括设计、实现、测试套件和安全审计)均通过 AI 辅助开发完成。尚未经过合格密码学家的独立人工同行评审。 **本软件不是经过认证的密码学产品,也未经过正式第三方安全评估。** 以下限制适用: - **不提供任何形式的担保**,明示或暗示,包括对特定用途的适用性或生产环境中的安全性。 - 基于 CBOR 的证书格式 **与 X.509、TLS 或任何标准 PKI 基础设施不兼容**。这是该库独有的自定义格式。 - 后量子密码标准是**近期标准化**的(FIPS 204:2024 年 8 月)。尽管 ML-DSA 被认为能抵抗已知的量子与经典攻击,但更广泛的生态系统(实现、工具链和操作指南)仍在成熟中。 - 正确的安全结果取决于调用者遵循 [`docs/security.md`](docs/security.md) 与 [`AUDIT.md`](AUDIT.md) 中的指导。错误使用 API —— 如跳过链验证、使用过期 CRL 或以不安全方式处理密钥 —— 无法被库阻止。 - 底层 `liboqs` C 库必须独立保持更新。`liboqs` 的安全修复不会通过更新此包自动应用。 **在生产环境或安全敏感环境中部署 `mlpki` 或其衍生作品前,请获得独立密码学家的安全审查。** ## 出口管制 本项目以开源形式发布,不受美国出口管制法规约束,属于公共领域豁免(EAR § 740.17(b)(1))。所使用的密码算法(ML-DSA / FIPS 204、AES-256-GCM)已由 NIST 公开标准化,且其实现在全球范围内均可自由获取。 ## 许可证 MIT
标签:AES-256-GCM, Argon2id, Authority Key ID, CBOR, CRL, CSR, CVE, Dilithium, FIPS 204, liboqs, ML-DSA, NIST PQC, PEM, Python, Python 3.11, XML 请求, 公钥基础设施, 吊销, 后量子密码, 安全开发, 安全规则引擎, 密码库, 密钥存储, 密钥对生成, 密钥用途标识, 序列化, 数字签名, 整数键, 无后门, 时间戳, 证书签发, 证书管理, 证书验证, 路径约束, 逆向工具, 量子安全, 链验证