前言
PKI 基礎設施的量子威脅
公開金鑰基礎建設(Public Key Infrastructure, PKI)是現代網路安全的基石,支撐著:
- HTTPS 加密通訊(全球 95%+ 網站)
- 程式碼簽章(軟體發布、App Store、Docker 映像)
- 電子郵件加密(S/MIME)
- VPN 與企業身份認證(IPsec、802.1X)
- 物聯網裝置認證(mTLS、OTA 更新)
傳統 PKI 完全依賴 RSA 與 ECDSA 簽章演算法,這些演算法在量子電腦面前將完全失效:
| 演算法 | 目前安全性 | 量子電腦攻擊 | 破解時間估算 |
|---|---|---|---|
| RSA-2048 | 112-bit 安全 | Shor’s Algorithm | ~8 小時(大型量子電腦) |
| RSA-4096 | 140-bit 安全 | Shor’s Algorithm | ~1 天 |
| ECDSA P-256 | 128-bit 安全 | Shor’s Algorithm | ~數小時 |
| ECDSA P-384 | 192-bit 安全 | Shor’s Algorithm | ~1 天 |
危機時間點:
- 2030-2035 年:預估為 RSA/ECDSA 安全終結
- 現在(2026):必須立即開始遷移準備
- 遷移週期:企業 PKI 遷移通常需要 3-5 年
混合憑證的必要性
問題:如果今天全面切換到後量子憑證(Pure PQC),會發生什麼?
災難性後果:
- 舊版瀏覽器(Chrome 90 以前、Safari 14 以前)無法驗證
- 嵌入式裝置(路由器、IoT)韌體無法更新
- 舊系統(Windows 7、Android 8)完全失去連線能力
- 全球數億台裝置瞬間「斷網」
混合憑證解決方案:
混合憑證 = 傳統演算法(ECDSA P-256)+ 後量子演算法(ML-DSA-65)
驗證策略:
- 舊客戶端:只驗證 ECDSA → 可以連線(量子不安全)
- 新客戶端:雙重驗證 ECDSA + ML-DSA → 量子安全!
- 升級路徑:逐步淘汰舊客戶端,最終只要求 ML-DSA
平滑遷移時間表:
| 階段 | 時間 | CA 配置 | 客戶端要求 |
|---|---|---|---|
| 階段 1 | 2026-2028 | 混合憑證(ECDSA + ML-DSA) | 只驗證 ECDSA |
| 階段 2 | 2028-2030 | 混合憑證 | 新客戶端開始驗證雙重簽章 |
| 階段 3 | 2030-2032 | 混合憑證 | 強制雙重驗證(舊客戶端淘汰) |
| 階段 4 | 2032+ | Pure PQC(僅 ML-DSA) | 只驗證 ML-DSA |
瀏覽器支援現況
Chrome 後量子密碼學部署進度:
TLS 金鑰交換(已部署)
Google Chrome 已經在 TLS 層面部署混合後量子金鑰交換,保護網路流量免受「現在收集,未來解密」(Harvest Now, Decrypt Later) 攻擊:
| Chrome 版本 | 發布時間 | 支援演算法 | 狀態 |
|---|---|---|---|
| Chrome 116 | 2023年8月 | X25519Kyber768 | ✅ 首次部署 |
| Chrome 131 | 2024年11月 | X25519 + ML-KEM-768(FIPS 203) | ✅ 切換到標準版本 |
部署成果(來源:Cloudflare 2025 報告):
- 📊 38% 的人類 HTTPS 流量已使用混合 PQC 握手(2025年3月)
- ⚡ 效能影響:TLS 握手時間增加 4%(server→client +1.1kB,client→server +1.2kB)
憑證簽章(規劃中)
相較於金鑰交換,後量子憑證簽章的部署面臨更大挑戰:
技術障礙:
- ML-DSA-44 簽章大小:2,420 bytes(傳統 ECDSA P-256 僅 ~64 bytes)
- ML-DSA-44 公鑰大小:1,312 bytes(ECDSA P-256 僅 65 bytes)
- 憑證鏈膨脹:X.509 憑證鏈可能超過 10kB,嚴重影響 TLS 握手效能
Chrome 團隊策略(來源:Chromium PQC PKI 設計文件):
- 🎯 效能目標:TLS 握手時間增加不超過 10%
- 🔬 研究方向:Merkle Tree Certificates (MTC),可將多數簽章替換為 <800 bytes 的 Merkle proof
- ⏳ 部署時程:
- 2025年底:部分 Root Program 試點接受 ML-DSA-87 一年期憑證
- 2026年:第一批 PQC 憑證出現(試驗性質)
- 2027年:PQC 憑證廣泛可用,被主流瀏覽器信任
- 2030年:NIST 建議所有 TLS 1.3 應完全使用 ML-KEM + ML-DSA
NG-CA 的應對策略:
- ✅ 支援混合憑證(ECDSA P-256 + ML-DSA-65),在效能與安全間取得平衡
- ✅ 複合簽章格式可靈活調整(目前 3,361 bytes,未來可切換至 ML-DSA-44 降至 ~2,500 bytes)
- ✅ 遵循 IETF draft-ietf-lamps-pq-composite-sigs 標準,確保未來相容性
為什麼選擇 Pure Rust(擺脫 OpenSSL)
傳統 CA 系統的問題:
大多數 CA 系統(如 EJBCA、Dogtag、Boulder)都依賴 OpenSSL:
// OpenSSL 的記憶體安全問題範例
char buffer[256];
strcpy(buffer, user_input); // Buffer Overflow
歷史漏洞(CVE 列表):
- Heartbleed (CVE-2014-0160):全球 17% 伺服器受影響
- Shellshock、POODLE、DROWN 等
- 每年平均 15+ 個重大漏洞
Pure Rust 優勢:
| 特性 | C/OpenSSL | Rust |
|---|---|---|
| 記憶體安全 | 需手動管理 | 編譯期保證 |
| 平行安全 | 手動同步 | 型別系統保證 |
| 空指標 | Segfault 風險 | 編譯期檢查(Option |
| 緩衝區溢位 | 常見漏洞 | 自動邊界檢查 |
| 釋放後使用 | Use-after-free | 生命週期系統防止 |
| 效能 | 極快 | 相同等級 |
NG-CA 雙軌技術棧:Pure Rust 處理 API / 業務邏輯 / 軟體 PQC(SLH-DSA、FN-DSA),Luna HSM 透過自有 luna-cryptoki crate(PKCS#11 v3.0 FFI)託管 RSA / ECC / ML-DSA / ML-KEM 金鑰。私鑰永遠不離開 HSM,僅以 KeyMaterial::HsmLabel(CKA_LABEL) 形式被應用層引用。
NG-CA 架構設計
系統整體架構(六層 + Luna HSM Bridge)

整體系統分為六層,L5 HSM Bridge 是 2026 年導入的關鍵層,把 RSA / ECC / ML-DSA / ML-KEM 的金鑰生命週期完全託管給 Luna HSM。SLH-DSA 與 FN-DSA 因 Luna 韌體尚未支援,仍走軟體實作(pqcrypto / RustCrypto)。為了在型別系統強制區分這兩種來源,金鑰素材改用 KeyMaterial enum 表示:
pub enum KeyMaterial {
/// 軟體實作的真實私鑰位元組(SLH-DSA / FN-DSA)
Software(Vec<u8>),
/// HSM-backed 私鑰的 CKA_LABEL UTF-8 bytes;實際私鑰永不離開 HSM
HsmLabel(Vec<u8>),
}
這個重構(Code review Issue #6)解決了原本 Vec<u8> 同時承擔兩種語意的歧義 —— 過去若把 HSM label 誤當成 PKCS#8 DER 解析,會在執行期才爆炸;現在編譯期就會被 enum match 強制檢查。
模組架構概要
核心模組(backend/src/):
- crypto/:密碼學核心層 — RSA / ECC / ML-DSA (PqcProvider) / SLH-DSA / FN-DSA / ML-KEM / Hybrid (兩種模式) + X.509 / CSR / Name Constraints
- hsm/:Luna HSM bridge —
luna-cryptoki包裝、connection pool、CKM_RSA_PKCS/CKM_ECDSA_SHA*/CKM_ML_DSA/CKM_ML_KEM_*mechanism 對映 - api/:RESTful API 層(CA 管理、憑證管理、verify-chain、錯誤處理)
- acme/:ACME v2 協議實作(RFC 8555,HTTP-01,JWS ES256/RS256 驗證)
- ocsp/:OCSP 實作(RFC 6960,含 Nonce 擴展、
next_update、moka cache) - validation/:Name Constraints、CSR Validator、台灣身份檢核
- metrics/:Prometheus exporter(25+ 指標)
- db/:SQLx (SQLite) —
ng-ca.db業務資料、audit.dbSOC2 稽核 - audit/:稽核日誌寫入(actor / action / resource / status / metadata)
前端技術架構
Vue 3 + TypeScript 實作:
- 頁面組件:Dashboard(儀表板)、CaList(CA 管理)、CertList(憑證管理)
- 功能組件:CreateCaDialog(CA 建立)、IssueCertDialog(憑證簽發)、CertDetailDialog(憑證詳情)
- 狀態管理:Pinia Store(CA 與憑證資料)
- 路由管理:Vue Router(頁面導航)
- API 層:Axios 客戶端(RESTful API 呼叫)
- 工具函數:日期格式化、表單驗證
資料庫架構
業務資料庫 (ng-ca.db) - CA 與憑證資料:
| 資料表 | 關鍵欄位 | 說明 |
|---|---|---|
| cas | id, name, algorithm | CA 實體,支援 RSA/ECC/ML-DSA/Hybrid 演算法 |
| public_key_pem, pqc_public_key_pem | 傳統與 PQC 公鑰(混合模式雙公鑰) | |
| private_key_bytes, pqc_private_key_bytes | 加密儲存的私鑰資料 | |
| parent_ca_id, is_ca, path_len | CA 階層架構(Root/Intermediate) | |
| default_days, default_key_usage | RA 策略配置 | |
| certificates | serial_number, subject, issuer_id | 已簽發憑證索引 |
| pem, status, not_before, not_after | 憑證內容與狀態(Good/Revoked) | |
| revoked_at | 撤銷時間戳記 |
索引策略:idx_cert_status(狀態查詢)、idx_cert_issuer(CA 關聯)、idx_cert_subject(主體查詢)
稽核資料庫 (audit.db) - SOC2 合規日誌:
| 資料表 | 關鍵欄位 | 說明 |
|---|---|---|
| audit_logs | id, timestamp, actor_ip | 操作時間與來源 IP |
| action, resource_type, resource_id | 操作類型(create_ca/issue_cert/revoke_cert)與目標資源 | |
| status, metadata | 操作結果與額外資訊(JSON) |
索引策略:idx_audit_timestamp(時間範圍查詢)、idx_audit_action(操作類型統計)
PQC 整合實現
18 個演算法、5 大類別總覽
NG-CA 在 2026 年 5 月的演算法支援已對齊 FIPS 203/204/205、即將發布的 FIPS 206、以及 RFC 9794/9881/9909 等最新規範:

5 大類別摘要:
| 類別 | 演算法 | Backend | 標準 |
|---|---|---|---|
| Traditional | RSA-2048/3072/4096、ECDSA P-256/384/521 | Luna HSM | FIPS 186-5 |
| PQ Signature (lattice) | ML-DSA-44/65/87 | Luna HSM | FIPS 204 / RFC 9881 |
| PQ Signature (hash-based) | SLH-DSA SHA2-128s/192s/256s | 軟體 | FIPS 205 / RFC 9909 |
| PQ Signature (FALCON) | FN-DSA-512/1024 | 軟體 | FIPS 206(預發布) |
| PQ KEM | ML-KEM-512/768/1024 | Luna HSM | FIPS 203 / draft-ietf-lamps-kyber-certificates |
Backend 邊界規則:
- Luna HSM 7.8+ 已支援 RSA、ECC、ML-DSA、ML-KEM 的硬體 keygen 與簽章/encap,所有此類金鑰皆走 HSM。
- SLH-DSA / FN-DSA Luna 尚未支援,落到軟體實作(
pqcrypto-sphincsplus/pqcrypto-falcon)。 - ML-KEM 為 KEM 演算法,KeyUsage 只能是
keyEncipherment,不可用於數位簽章;NG-CA 在 keygen 與用途檢查時都會拒絕誤用。
ML-DSA 詳解(最常用的 PQC 簽章)
FIPS 204 / RFC 9881(2025-10)
| 模式 | NIST 等級 | 公鑰 | 私鑰 | 簽章 | OID |
|---|---|---|---|---|---|
| ML-DSA-44 (原 Dilithium2) | Level 2 | 1,312 B | 2,544 B | 2,420 B | 2.16.840.1.101.3.4.3.17 |
| ML-DSA-65 (原 Dilithium3) | Level 3 | 1,952 B | 4,000 B | 3,309 B | 2.16.840.1.101.3.4.3.18 |
| ML-DSA-87 (原 Dilithium5) | Level 5 | 2,592 B | 5,632 B | 4,627 B | 2.16.840.1.101.3.4.3.19 |
HSM-backed 流程(Luna 7.8+):
- 金鑰產生:呼叫
CKM_ML_DSA_KEY_PAIR_GEN,私鑰留在 HSM,回傳CKA_LABEL與公鑰位元組 - 公鑰編碼:以 SPKI 標準格式(AlgorithmIdentifier + BitString)寫入 PEM;AlgorithmIdentifier 的
parametersMUST be absent(RFC 9881 §3) - 簽章:從應用層送入
CKM_ML_DSA的C_SignInit + C_Sign,HSM 內部完成簽章運算,私鑰不離開硬體 - 驗證:軟體側完成(
pqcrypto-mldsa),因驗證只需公鑰,沒有金鑰外洩風險
OID 自動識別:解析 SPKI 時從 AlgorithmIdentifier 對照三組固定 OID 即可決定演算法版本,不需要額外 metadata。
混合憑證 (Hybrid Certificates) — 兩種並存模式
NG-CA 同時實作 RFC 9794 定義的兩種 hybrid 模式。這是相對於早期版本(只實作自訂 [ecc_len][ecc_sig][pqc_sig] 連接格式)的重大標準化升級:

| 模式 | NG-CA enum | RFC 9794 術語 | X.509 表現 | 客戶端要求 |
|---|---|---|---|---|
| non-composite | Algorithm::Hybrid | non-composite | 主簽章 + ITU-T v3 alt-sig extensions(OID 2.5.29.72/73/74) | 舊 client 只驗主簽即可連線 |
| composite | Algorithm::HybridDualSignature | composite | 單一複合 OID(1.3.6.1.5.5.7.6.*)+ SEQUENCE OF BIT STRING (size 2) | 必須是 hybrid-aware client |
兩種模式分別解決不同情境:
- non-composite(漸進式遷移友好):適合需要與既有 PKI 共存、不能切斷舊裝置連線的場景。BSI 對德國關鍵基礎設施的 hybrid 強制要求恰好對應這條路。
- composite(draft-ietf-lamps-pq-composite-sigs-19):適合純新建的 PQC 基礎設施。簽章 / 公鑰皆為標準的
SEQUENCE OF BIT STRING (size 2)結構,加入 32-byte domain separator 與 SHA-512 pre-hashing 防跨組合 spoofing;對協議層透明,不需要新增 alt-sig 處理邏輯。
Hybrid 金鑰對產生
兩種模式都需要兩組金鑰 — 但因 RSA / ECC / ML-DSA 全部已 HSM-backed,私鑰側其實是兩個 CKA_LABEL:
pub struct HybridKeyPair {
pub traditional: KeyPair, // RSA / ECC / Ed25519,KeyMaterial::HsmLabel
pub pqc: KeyPair, // ML-DSA-44/65/87,KeyMaterial::HsmLabel
}
產生流程:
- 呼叫
EccProvider::generate()(或 RSA)→ LunaCKM_*_KEY_PAIR_GEN→KeyMaterial::HsmLabel(label_a) - 呼叫
PqcProvider::generate(MlDsa65)→ LunaCKM_ML_DSA_KEY_PAIR_GEN→KeyMaterial::HsmLabel(label_b) - 組成
HybridKeyPair,DB 只儲存兩個 label 與兩份 SPKI 公鑰
資料庫欄位(cas 表):
algorithm='Hybrid'或'HybridDualSignature'(區分兩種模式)public_key_pem= 傳統公鑰 SPKIpqc_public_key_pem= ML-DSA 公鑰 SPKIprivate_key_bytes/pqc_private_key_bytes= HSM 上對應的CKA_LABELUTF-8 bytes(不是真私鑰)
雙重簽章運算
兩種模式的 sign/verify 介面相同(都吃 tbs_data: &[u8] 回傳 Vec<u8>),但內部封裝不同:
non-composite (Algorithm::Hybrid) —— 兩段獨立 BIT STRING,各自寫入 X.509 不同欄位:
(主) signatureValue = Sign_ECDSA(tbsCertificate)
(副) altSignatureValue = Sign_MLDSA65(tbsCertificate)
副簽放入 v3 extension 2.5.29.74;對應的演算法 OID 放入 2.5.29.73;對應的 ML-DSA 公鑰放入 2.5.29.72(subjectAltPublicKeyInfo)。
composite (Algorithm::HybridDualSignature) —— 一段 ASN.1 SEQUENCE OF BIT STRING (size 2):
CompositeSignatureValue ::= SEQUENCE SIZE (2) OF BIT STRING
-- [0] = ML-DSA signature
-- [1] = traditional signature
CompositeSignaturePublicKey ::= SEQUENCE SIZE (2) OF BIT STRING
-- [0] = ML-DSA public key
-- [1] = traditional public key
Pre-hashing 細節:composite 模式要求兩個演算法簽同一份摘要(不是原始訊息)。對 1.3.6.1.5.5.7.6.45(ML-DSA-65 + ECDSA-P256-SHA512)來說,計算流程是:
M' = SHA-512( domain_separator(32 bytes) || tbs_data )
sig_mldsa = MLDSA65.Sign(M')
sig_ecdsa = ECDSA.Sign(M')
output = SEQUENCE { sig_mldsa, sig_ecdsa }
每個 composite OID 對應一組唯一的 32-byte domain separator,避免「把同一段 tbs 在不同 OID 之間移植」的攻擊。
驗證:non-composite 由憑證解析器先處理 v3 extension、再分別走兩個 verifier;composite 由 OID 直接派發到 CompositeVerifier,內部解 SEQUENCE 後並行驗證 — 任一失敗整體失敗(沒有「向下相容只驗一邊」的選項)。詳細決策樹見下節。
X.509 延伸欄位(ITU-T X.509 Extensions)
標準 X.509 憑證結構:
Certificate ::= SEQUENCE {
tbsCertificate TBSCertificate,
signatureAlgorithm AlgorithmIdentifier,
signatureValue BIT STRING
}
TBSCertificate ::= SEQUENCE {
version [0] EXPLICIT Version DEFAULT v1,
serialNumber CertificateSerialNumber,
signature AlgorithmIdentifier,
issuer Name,
validity Validity,
subject Name,
subjectPublicKeyInfo SubjectPublicKeyInfo,
extensions [3] EXPLICIT Extensions OPTIONAL
}
混合憑證延伸欄位(基於 IETF Draft):
extensions [3] EXPLICIT SEQUENCE {
-- 1. Subject Alt Public Key Info (OID 2.5.29.72)
Extension {
extnID = id-ce-subjectAltPublicKeyInfo,
critical = FALSE,
extnValue = OCTET STRING (containing ML-DSA-65 public key)
},
-- 2. Alt Signature Algorithm (OID 2.5.29.73)
Extension {
extnID = id-ce-altSignatureAlgorithm,
critical = FALSE,
extnValue = AlgorithmIdentifier (ML-DSA-65 algorithm)
},
-- 3. Alt Signature Value (OID 2.5.29.74)
Extension {
extnID = id-ce-altSignatureValue,
critical = FALSE,
extnValue = BIT STRING (ML-DSA-65 signature)
}
}
混合憑證建構邏輯(使用 x509-cert crate):
關鍵 OID 定義:
2.5.29.72→ Subject Alt Public Key Info2.5.29.73→ Alt Signature Algorithm2.5.29.74→ Alt Signature Value2.16.840.1.101.3.4.3.17→ ML-DSA-44 演算法2.16.840.1.101.3.4.3.18→ ML-DSA-65 演算法2.16.840.1.101.3.4.3.19→ ML-DSA-87 演算法
ML-DSA OID 來源:IETF draft-ietf-lamps-dilithium-certificates
建構流程:
- 準備 TBS Certificate:序列化 TbsCertificate 為 DER 格式
- 產生雙重簽章:呼叫 DualSignatureProvider 產生複合簽章
- 解析簽章:從複合簽章中分離 ECC 與 PQC 簽章
- 添加三個 X.509 延伸:
Subject Alt Public Key Info:儲存 ML-DSA-65 公鑰Alt Signature Algorithm:標記 ML-DSA-65 演算法 OIDAlt Signature Value:儲存 PQC 簽章
- 組合憑證:
- 主
signatureAlgorithm使用 ECDSA with SHA-256 - 主
signature使用 ECC 簽章 - Extensions 包含 PQC 公鑰與簽章
- 主
憑證驗證決策樹:
NG-CA 的 verify_certificate() 依 signatureAlgorithm OID 與 v3 extensions 分派至三條路徑 — 涵蓋 single signature、non-composite hybrid、composite hybrid 三種情境:

三條路徑摘要:
- Lane A(Single Signature):傳統 OID 且無 alt-sig extensions,依 OID 派發 RSA / ECDSA / ML-DSA / SLH-DSA 對應 verifier。最常見,路徑最短。
- Lane B(non-composite Hybrid):傳統 OID 但有 v3 alt-sig extensions(
2.5.29.72/73/74)。先驗主簽(向下相容老 client),再從 extensions 取 PQC 公鑰與 alt-sig 補上量子安全層。如果 client 看不懂 alt-sig 它仍能信任主簽,憑證 graceful degradation。 - Lane C(composite Hybrid):simgnatureAlgorithm 是 composite OID(
1.3.6.1.5.5.7.6.*)。先依 OID 查到演算法配對,解SEQUENCE OF BIT STRING (size 2)後 pre-hash → 兩個 verifier 並行驗證;任一失敗整體失敗。沒有向下相容,這是設計選擇。
完整鏈驗證(/api/v1/certificates/{serial}/verify-chain)會遞迴對 End-Entity → Intermediate → Root 每一層套用上述判斷,pathLenConstraint 也在每層檢查;moka cache(10k entries / 5min TTL)加速重複查詢。
CA 功能實作
Root CA 建立
API 端點: POST /api/v1/ca
請求體:
{
"name": "Example Root CA",
"algorithm": "Hybrid", // Rsa2048/EccP256/MlDsa65/Hybrid
"is_ca": true, // BasicConstraints.cA
"path_len": 2, // 允許 2 層 Intermediate CA
"default_days": 3650, // 預設憑證有效期 10 年
"use_v3_extensions": true,
"default_key_usage": "digitalSignature,keyCertSign,cRLSign",
"default_extended_key_usage": "serverAuth,clientAuth"
}
後端處理流程:
-
金鑰對產生:
- 根據
algorithm參數選擇對應的 Provider(Hybrid/MlDsa65/EccP256/Rsa2048) - 呼叫對應 Provider 的
generate()方法產生金鑰對 - 包裝成
KeyPairEnum統一介面
- 根據
-
自簽憑證建構:
- 產生隨機序號(20 bytes)
- 設定 Subject/Issuer(自簽相同)
- 計算有效期(
default_days天數) - 添加 BasicConstraints 延伸(
ca與path_len) - 添加 KeyUsage 延伸(CA 需
digitalSignature, keyCertSign, cRLSign) - 若為混合憑證,呼叫
build_hybrid_certificate()添加 PQC 延伸
-
資料庫儲存:
- 插入
cas表,儲存金鑰對(傳統與 PQC) - 儲存配置(
is_ca,path_len,default_days, Key Usage) - 取得
ca_id(auto-increment)
- 插入
-
稽核日誌:
- 記錄
create_ca操作 - 包含 CA 名稱、演算法、操作結果
- 記錄
-
回傳結果:
ca_id、CA 名稱、憑證 PEM、演算法類型
自簽憑證建構邏輯:
- 已整合至上述「後端處理流程」的第 2 步驟
Intermediate CA 支援
CA 階層架構(透過 parent_ca_id 與 path_len 控制):
| CA 層級 | parent_ca_id | path_len | 說明 |
|---|---|---|---|
| Root CA | NULL | 2 | 允許建立 2 層子 CA |
| Intermediate CA (L1) | 1 | 1 | 允許建立 1 層子 CA |
| Intermediate CA (L2) | 2 | 0 | 無法再建立子 CA(終端 CA) |
憑證鏈驗證邏輯:
- 從目標憑證開始,讀取對應的 CA 資訊
- 使用 CA 公鑰驗證憑證簽章
- 若
parent_ca_id為 NULL,表示到達 Root CA,驗證完成 - 若有
parent_ca_id,讀取父 CA 憑證,重複步驟 2-3 - 迴圈驗證整條憑證鏈,任一環節失敗則回傳 false
CSR 簽發流程
API 端點: POST /api/v1/ca/{ca_id}/issue
處理流程:
-
解析與驗證 CSR:
- 從 PEM 格式解析 CSR
- 驗證 CSR 內建簽章(確保 CSR 未被竄改)
-
讀取 CA 配置:
- 從資料庫讀取 CA 資訊(包含金鑰、策略設定)
-
應用驗證規則(可選):
- 若 CA 設定了
csr_validation_regex,驗證 Subject DN - 支援台灣身份證號/統一編號驗證(詳見下節)
- 若 CA 設定了
-
產生憑證:
- 產生隨機序號(20 bytes)
- 從 CSR 提取公鑰與 Subject
- 使用 CA 私鑰簽署憑證
- 應用 CA 預設的 Key Usage 與有效期
-
儲存與稽核:
- 插入
certificates表(狀態為 ‘Good’) - 記錄稽核日誌(
issue_cert操作) - 回傳序號與憑證 PEM
- 插入
憑證撤銷與 CRL
撤銷憑證流程:
- 更新
certificates表:設定status = 'Revoked',記錄revoked_at時間戳記 - 檢查影響行數,若為 0 則回傳憑證不存在錯誤
- 記錄稽核日誌(
revoke_cert操作) - 回傳撤銷成功訊息
CRL 產生邏輯:
- 讀取 CA 資訊與私鑰
- 查詢該 CA 所有已撤銷憑證(
status = 'Revoked') - 使用
x509-certcrate 建構 CertificateList:- 設定 CRL 簽發者(CA 名稱)
- 設定 CRL 有效期(預設 7 天)
- 逐一添加 RevokedCert 項目(序號 + 撤銷時間)
- 使用 CA 私鑰簽署 CRL
- 轉換為 PEM 格式回傳
企業級進階功能
NG-CA 在 2026 年初完成了多項企業級功能實現,顯著提升系統的可觀測性、安全性和功能完整性。
Prometheus 監控系統
實現時間:2026 年 2 月 NG-CA 整合完整的 Prometheus 監控指標系統,提供生產環境所需的全面可觀測性:
監控指標類別(25+ 個關鍵指標):
| 類別 | 指標範例 | 用途 |
|---|---|---|
| OCSP 服務 | ocsp_requests_totalocsp_request_duration_seconds | OCSP 請求量、響應延遲 Nonce 使用率追蹤 |
| CRL 管理 | crl_generated_totalcrl_size_bytes | Full/Delta CRL 生成統計 CRL 大小分布 |
| 憑證管理 | certificates_issued_totalcertificates_active | 簽發總數(按演算法分類) 活動憑證數量 |
| 效能指標 | cache_hit_rate_percentdb_query_duration_seconds | 快取命中率 資料庫查詢延遲 |
API 端點:
GET /metrics- Prometheus 格式指標導出
效能影響:
- CPU 開銷:<1%
- 記憶體使用:+10-50MB
- 每請求延遲:~1-5μs
使用場景:
- 生產環境性能監控和 SLA 追蹤
- 容量規劃與異常檢測
- Grafana Dashboard 視覺化
名稱約束 (Name Constraints)
實現時間:2026 年 2 月 實現 RFC 5280 名稱約束功能,允許 CA 限制其簽發的憑證只能用於特定網域、IP 或 Email 範圍:
支援的約束類型:
| 約束類型 | 範例 | 驗證邏輯 |
|---|---|---|
| DNS 網域 | *.example.com | 支援 wildcard 匹配 |
| IP 位址 | 192.168.0.0/162001:db8::/32 | 支援 IPv4/IPv6 CIDR |
*@example.com | 支援 pattern 匹配 |
工作流程:
- CA 建立時設定約束:在
permitted_subtrees/excluded_subtrees欄位指定規則 - CSR 解析:提取 Subject CN 和所有 SAN(DNS、IP、Email)
- 簽發驗證:自動檢查 CSR 內容是否符合名稱約束
- 錯誤回報:明確指出違反哪一條約束規則
安全效益:
- 防止 Intermediate CA 簽發超出授權範圍的憑證
- 支援企業內部 CA 的網域隔離策略
- 符合 RFC 5280 §4.2.1.10 標準
VA 功能增強套件
實現時間:2026 年 2 月
完成憑證驗證功能,大幅提升系統安全性與效能:
1. OCSP Nonce 擴展(RFC 6960 §4.4.1)
功能:防止 OCSP 重放攻擊
- 在 OCSP 請求中提取 Nonce 擴展
- 在響應中回顯相同的 Nonce
- 確保響應的時效性
安全效益:攻擊者無法重用舊的 OCSP 響應
2. 憑證狀態快取機制
技術實現:
- 使用
moka記憶體快取庫 - TTL:5 分鐘
- 容量:10,000 條目
效能提升:
- OCSP 查詢速度提升 10 倍
- 資料庫負載降低 80-90%
3. 憑證路徑驗證 API(RFC 5280 §6)
功能:完整的憑證鏈驗證
- 遞迴建構信任鏈(End-Entity → Intermediate → Root)
- 路徑長度約束檢查(
pathLenConstraint) - 驗證每一層簽章有效性
API 端點:
GET /api/v1/certificates/{serial}/verify-chain
使用場景:
- 驗證憑證是否由信任的 Root CA 簽發
- 檢查憑證鏈的完整性
- 偵測中間人攻擊
4. Delta CRL 支援(RFC 5280 §5.2.4)
功能:增量撤銷清單生成
- 只包含自上次 Full CRL 後的新撤銷憑證
- 版本追蹤系統(Base CRL Number)
- 支援標準和混合簽章
效能優化:
- CRL 傳輸量減少 95-99%
- 降低頻寬成本和客戶端處理負擔
API 端點:
GET /api/v1/ca/{id}/crl/delta
RSA Hash 演算法擴展
實現時間:2026 年 2 月
擴展 RSA 簽章的 hash 演算法支援,適用於所有 RSA 金鑰大小(2048/3072/4096):
新增支援:
- ✅ SHA-384
- ✅ SHA-512
- ✅ SHA3-384
- ✅ SHA3-512
應用場景:
- 高安全需求環境(政府、金融機構)
- 符合特定合規要求(如 CNSA 2.0)
- RSA-4096 與 SHA-512 組合提供 256-bit 安全等級
測試通過率提升
成果:
- 2026 年 1 月:71/71 測試通過(100%)
- 整體測試涵蓋率:99%+
測試類別:
- ✅ 密碼學核心測試(11/11)
- ✅ OCSP 增強測試(全部通過)
- ✅ Delta CRL 測試(全部通過)
- ✅ 路徑驗證測試(全部通過)
- ✅ 名稱約束測試(全部通過)
ACME v2 協議整合
ACME 協議概述
ACME (Automatic Certificate Management Environment) 是由 Let’s Encrypt 推動的自動化憑證管理協議,已標準化為 RFC 8555。
ACME v2 完整流程(HTTP-01 Challenge):
NG-CA 已實作 RFC 8555 主要端點,目前以 HTTP-01 為主要驗證方式。完整訊息流程如下:

關鍵實作細節:
- JWS 防重放:每個請求帶上一個
nonce(從acme_nonces表取出後立即標記為 used),任何重複使用的 nonce 都會被拒絕。 - JWS 演算法:目前生產支援 ES256(ECDSA P-256)與 RS256(RSA-2048+ PKCS#1 v1.5);EdDSA 規劃中。
- HTTP-01 驗證:NG-CA server 主動向
http://<domain>/.well-known/acme-challenge/{token}發 GET,比對key authorization = token || '.' || base64url(SHA-256(JWK))。 - 狀態機:
acme_orders.status走pending → ready → processing → valid|invalid,每次轉換寫入audit_logs。 - PQC roadmap:composite OID 的 ACME 簽發已可透過 finalize 階段傳入 hybrid CSR;CA/B Forum 對 TLS BR 的 PQC 修訂預計 2026-2027 落地後可開放公開簽發。
- 為什麼非要 ACME 自動化:TLS / Code Signing 整個產業正快速縮短憑證有效期 — Code Signing 從 39 月降到 460 天、TLS 預計 2029 年降至 47 天。NG-CA 把 ACME v2 列為核心模組,正是因為人工續期在 47-day 週期下根本不可行;PQC 演算法輪替(ML-DSA → SLH-DSA / FN-DSA)疊加在這條趨勢上,自動化簽發 + 撤銷管線是 PQC CA 不可妥協的基礎能力。
支援的 ACME 端點
實作狀態(backend/src/acme/routes.rs):
| 端點 | 方法 | 功能 | 狀態 |
|---|---|---|---|
/acme/directory | GET | 取得 ACME 目錄 | 已完成 |
/acme/new-nonce | HEAD/GET | 取得 nonce | 已完成 |
/acme/new-account | POST | 註冊帳號 | 已完成 |
/acme/acct/{id} | POST-as-GET | 查詢帳號資訊 | 已完成 |
/acme/new-order | POST | 建立訂單 | 已完成 |
/acme/authz/{id} | POST-as-GET | 查詢授權狀態 | 已完成 |
/acme/chall/{id} | POST | 回應 Challenge | 部分完成 |
/acme/order/{id}/finalize | POST | 完成訂單(提交 CSR) | 規劃中 |
/acme/cert/{serial} | POST-as-GET | 下載憑證 | 已完成 |
JWS 簽名驗證
ACME 要求所有請求都使用 JWS (JSON Web Signature) 簽名(RFC 7515):
支援的演算法:
| 演算法 | 類型 | 金鑰類型 | 狀態 |
|---|---|---|---|
| ES256 | ECDSA with SHA-256 | P-256 | 已完成 |
| RS256 | RSA PKCS#1 v1.5 with SHA-256 | RSA-2048+ | 已完成 |
| EdDSA | Ed25519 | Ed25519 | 規劃中 |
JWS 驗證邏輯:
資料結構:
JwsHeader:包含alg(演算法)、nonce(防重放)、url(請求 URL)、kid(帳號 ID)、jwk(公鑰)Jwk(JSON Web Key):包含kty(金鑰類型)、EC 參數(crv,x,y)或 RSA 參數(n,e)
驗證流程:
-
解析 JWS:
- 格式為
header.payload.signature(三段 Base64 URL編碼) - 檢查格式正確性
- 格式為
-
驗證安全參數:
- 解碼 header 並檢查
nonce(防重放攻擊) - 檢查
url是否匹配請求路徑
- 解碼 header 並檢查
-
簽章驗證(依演算法):
- ES256(ECDSA P-256):
- 從 JWK 解析 P-256 公鑰(
x,y座標) - 使用
p256crate 驗證 ECDSA 簽章
- 從 JWK 解析 P-256 公鑰(
- RS256(RSA PKCS#1 v1.5):
- 從 JWK 解析 RSA 公鑰(
nmodulus,eexponent) - 使用
rsacrate 驗證 PKCS#1 v1.5 簽章
- 從 JWK 解析 RSA 公鑰(
- ES256(ECDSA P-256):
-
解碼 Payload:
- Base64 URL 解碼 payload
- 反序列化為 JSON 結構
ACME 資料庫架構
| 資料表 | 關鍵欄位 | 說明 |
|---|---|---|
| acme_nonces | nonce, created_at, used | 防重放攻擊(nonce 一次性使用) |
| acme_accounts | id, account_key_jwk, contact, status | ACME 帳號(儲存 JWK 公鑰與聯絡方式) |
| acme_orders | id, account_id, status, identifiers | 憑證訂單(狀態:pending/ready/processing/valid/invalid) |
| certificate_serial, expires | 簽發後的憑證序號與訂單過期時間 | |
| acme_authorizations | id, order_id, identifier, status | 域名授權(每個 identifier 一筆記錄) |
| challenge_type, challenge_token | Challenge 類型(http-01/dns-01)與驗證 token | |
| challenge_status, validated_at | Challenge 狀態與驗證時間 |
台灣特色驗證
身份證字號驗證
格式:1 個英文字母 + 9 個數字(範例:A123456789)
驗證邏輯(依內政部規定):
- 格式檢查:長度 10 碼,首碼英文,後 9 碼數字
- 英文字母轉數字:A=10, B=11, …, Z=35(I=34, O=35 為特殊對應)
- 拆分英文數值:轉換後的數字拆成十位數(d1)與個位數(d2)
- 權重計算:
- 權重序列:
[1, 9, 8, 7, 6, 5, 4, 3, 2, 1] - 加權總和:
d1×1 + d2×9 + digit[0]×8 + ... + digit[8]×1
- 權重序列:
- 檢查碼驗證:加權總和
% 10 == 0
測試案例:A123456789(✅)、F131104093(✅)、A123456788(❌ 檢查碼錯誤)
統一編號驗證
格式:8 個數字(範例:12345678)
驗證邏輯(依財政部規定):
- 格式檢查:長度 8 碼,全數字
- 權重計算:
- 權重序列:
[1, 2, 1, 2, 1, 2, 4, 1] - 每個
digit[i] × weight[i]的乘積拆分為十位數與個位數後加總
- 權重序列:
- 特殊規則:
- 若第 7 碼為 7,則
sum % 10 == 0或(sum + 1) % 10 == 0 - 其他情況:
sum % 10 == 0
- 若第 7 碼為 7,則
CSR Subject 驗證整合
驗證流程:
- 從 CSR 的 Subject DN 中解析 CN (Common Name)
- 根據 CA 的
csr_validation_regex設定選擇驗證方法:"TW_ID"→ 台灣身份證字號驗證"TW_TAX_ID"→ 統一編號驗證"TW_ORG_ID"→ 組織機構代碼驗證- 自定義 regex → 使用正則表達式比對 CN
使用情境:
- CA 管理員在建立 CA 時設定
csr_validation_regex - 簽發憑證時自動檢查 CSR 的 CN 是否符合規則
- 驗證失敗則拒絕簽發憑證
前端管理介面
Vue 3 技術棧
核心依賴:
- Vue 3.5 + TypeScript:組件化架構
- Vue Router 4:頁面路由管理
- Pinia 3:狀態管理
- Axios:HTTP 客戶端(含自動重試)
- Vite 6:開發伺服器與建置工具
- Tailwind CSS 4:樣式框架
- Lucide Icons:圖示庫
儀表板組件
主要功能 (Dashboard.vue):
資料展示:
- 統計卡片:顯示 CA 總數、已簽發憑證數、已撤銷憑證數(使用
StatCard可復用組件) - CA 列表表格:展示所有 CA,包含名稱、演算法類型(顏色徽章)、CA 類型、建立時間
互動功能:
onMounted:載入統計資料與 CA 列表(呼叫/api/v1/stats與/api/v1/ca)algorithmBadgeClass():根據演算法類型回傳對應的 Tailwind CSS class(Hybrid=紫色、ML-DSA=藍色、ECC=綠色、RSA=灰色)downloadCRL():下載指定 CA 的 CRL(呼叫/api/v1/ca/{id}/crl,透過 Blob 觸發瀏覽器下載)
實際介面截圖
以下是 NG-CA 管理介面的實際畫面:
Dashboard 儀表板

主要功能:
- 統計卡片:顯示 CA 總數、已簽發憑證數、已撤銷憑證數
- CA 列表:展示所有 CA,標示演算法類型(Hybrid/ML-DSA/ECC)
- 快速操作:下載 CRL、查看 CA 詳情
CA 列表視圖

顯示資訊:
- CA 名稱與 ID
- 演算法類型(使用顏色徽章區分)
- 🟣 紫色:Hybrid (ECC + ML-DSA)
- 🔵 藍色:ML-DSA-65
- 🟢 綠色:ECC P-256
- CA 類型(Root CA / Intermediate CA)
- 建立時間
- 操作按鈕(下載憑證、下載 CRL、撤銷)
憑證列表視圖

顯示資訊:
- 憑證 Subject(Common Name)
- 簽發 CA
- 有效期限(起始/結束日期)
- 憑證狀態(✅ 有效 / ❌ 已撤銷 / ⏰ 即將過期)
- 操作(下載憑證、撤銷憑證、查看詳情)
CA 建立對話框
表單欄位 (CreateCaDialog.vue):
- CA 名稱:文字輸入(必填)
- 演算法選擇:下拉選單(Hybrid/ML-DSA-65/ECC P-256/RSA-2048)
- CA 類型:核取方塊(是否為 CA 憑證)
- 路徑長度限制:數字輸入(僅 CA 憑證,0-5 層)
- 預設有效期:數字輸入(1-3650 天)
互動邏輯:
handleSubmit():呼叫POST /api/v1/ca建立 CA- 成功後顯示 Toast 通知,關閉對話框,重新載入頁面
- 錯誤處理:顯示 API 回傳的錯誤訊息或預設「建立失敗」
- 提交期間禁用按鈕,顯示「建立中…」載入狀態
安全性與合規
FIPS 140-3 對齊(HSM 整合後現況)
2026 年初的 Phase A-C HSM 整合完成後,FIPS 140-3 遵循度從原型期的 2/10 大幅提升 — 因為所有受 FIPS 規範的密碼學運算都委派給 Thales Luna HSM(FIPS 140-3 Level 3 認證模組),NG-CA 應用層只剩編排與資料整合:
| 項目 | 現況 | 認證來源 |
|---|---|---|
| 密碼學模組 | RSA / ECC / ML-DSA / ML-KEM 在 Luna 內運算 | Luna HSM FIPS 140-3 Level 3 |
| 金鑰儲存 | CKA_LABEL only;私鑰永不離開 HSM | HSM 物理保護 |
| 隨機數產生 | Luna HSM 內部的 hardware RNG(FIPS 通過) | Luna 認證 |
| 軟體 PQC | SLH-DSA / FN-DSA 走 RustCrypto/pqcrypto | NIST 標準參考實作(待 CMVP 認證) |
| 自我測試 | Luna 開機自檢;NG-CA 啟動時 connection probe | HSM POST + 應用層健檢 |
| 稽核 | SOC2-ready audit.db,每次 sign / issue / revoke 寫入 | RFC 5424 等級結構化日誌 |
| 演算法支援 | 全 FIPS 186-5 + FIPS 203/204;待 FIPS 205/206 完整對齊 | NIST 最新標準 |
剩餘缺口(路線圖):
- SLH-DSA / FN-DSA HSM 化:等待 Luna 後續韌體開放(一旦支援,現有
KeyMaterialenum 切換即可,API 不變) - CMVP 系統認證:Luna 已認證,但「NG-CA + Luna 整合」整體仍需走 ISO/IEC 17025 流程
- FIPS 140-3 Level 4:物理破壞偵測,預計搭配 Luna 高階機型
私鑰生命週期:永不離開 HSM
舊版 NG-CA 計畫用 AES-256-GCM 加密私鑰後存進 SQLite,這個方案在 Phase B 完成後已完全廢棄。所有受 FIPS 規範的金鑰(RSA / ECC / ML-DSA / ML-KEM)走以下生命週期:
1. keygen → Luna PKCS#11 C_GenerateKeyPair
├─ 私鑰留在 HSM partition,標記為 CKA_PRIVATE = true
└─ 應用層只取得 CKA_LABEL(UTF-8 string)與公鑰位元組
2. 儲存 → ng-ca.db.cas.private_key_bytes = CKA_LABEL(不是私鑰!)
3. sign → C_SignInit(CKA_LABEL) + C_Sign(message)
簽章運算在 HSM 內完成;應用層只看到輸出 bytes
4. 銷毀 → C_DestroyObject(CKA_LABEL);DB 行同步刪除
KeyMaterial enum 把這層語意搬到型別系統 — 若呼叫端嘗試把 HsmLabel(...) 餵進 PKCS#8 解析器,會在編譯期被擋下。對 SLH-DSA / FN-DSA 等仍走軟體實作的演算法,私鑰才以 KeyMaterial::Software(...) 形式儲存(短期內仍考慮上層加密儲存)。
生產環境的 HSM 配置:
HSM_MODULE_PATH=/usr/safenet/lunaclient/lib/libCryptoki2_64.so
HSM_SLOT_ID=0
HSM_PIN=<透過 systemd LoadCredential 或 secret manager 注入>
HSM_POOL_SIZE=16
HSM_POOL_SIZE 控制 connection pool 上限(預設 16),實測在 6 vCPU 機器上能達到 ~4000 sig/s(ECDSA P-256)。
測試與驗證
測試涵蓋率
整體統計(2026 年 5 月):71/71 測試通過(100%) — 從 v0.2 的 53/54 升級到 v1.0 後保持滿分
| 測試套件 | 重點驗證 | 位置 |
|---|---|---|
| 密碼學核心 | RSA / ECC / ML-DSA / SLH-DSA / FN-DSA / ML-KEM 完整 keygen-sign-verify | backend/tests/coverage_tests.rs |
| HSM 整合測試 | luna-cryptoki keygen、CKM_* mechanism、connection pool | backend/tests/hsm_*.rs |
| Hybrid 雙模式 | non-composite + composite 兩條路徑各自簽發/驗證 | backend/tests/hybrid_*.rs |
| API 端點 | CA CRUD、issue、revoke、verify-chain | backend/tests/api_tests.rs |
| ACME 協議 | 完整 RFC 8555 流程 + JWS ES256 / RS256 | backend/tests/acme_*.rs |
| OCSP 增強 | Nonce 擴展、moka cache、next_update | backend/tests/ocsp_enhanced_tests.rs |
| Delta CRL | base CRL number、增量產出 | backend/tests/delta_crl_tests.rs |
| 路徑驗證 | 多層 chain、pathLenConstraint | backend/tests/path_validation_tests.rs |
| 名稱約束 | DNS / IP / Email permitted/excluded | backend/tests/name_constraints_tests.rs |
| 負面測試 | 偽造簽章、過期憑證、撤銷後存取 | backend/tests/negative_tests.rs |
密碼學核心測試
測試案例涵蓋:
ML-DSA-65 完整工作流程測試 (test_ml_dsa_65_full_workflow):
- 金鑰對產生:驗證公鑰 PEM 與私鑰 bytes 非空,私鑰大小為 4000 bytes
- 簽章產生:驗證簽章大小為 3293 bytes(ML-DSA-65 規格)
- 簽章驗證:驗證合法簽章通過
- 負面測試:驗證偽造訊息的簽章驗證失敗
混合雙重簽章測試 (test_hybrid_dual_signature):
- 混合金鑰對產生:包含 ECC 與 ML-DSA 兩組金鑰
- 雙重簽章:產生複合簽章(格式:[ecc_len][ecc_sig][pqc_sig])
- 驗證複合簽章格式:檢查 ECC 簽章長度是否合理(0-200 bytes)
- 雙重驗證:驗證兩個簽章都有效
- 負面測試:篡改任一簽章後驗證應失敗
RSA 與 ECC 工作流程測試:
- RSA-2048/3072/4096:驗證金鑰產生、簽章大小(256/384/512 bytes)、簽章驗證
- ECC P-256/384/521:驗證金鑰產生、簽章大小(~64/96/132 bytes)、簽章驗證
X.509 憑證建構測試:
- 基本 X.509 欄位:序號、Subject、Issuer、有效期
- BasicConstraints 延伸:CA 標記、路徑長度限制
- KeyUsage 延伸:digitalSignature、keyCertSign、cRLSign
- 混合憑證延伸:Subject Alt Public Key Info、Alt Signature Algorithm、Alt Signature Value
OpenSSL 互通性驗證
驗證腳本(scripts/verify_openssl.sh):
驗證步驟:
- 取得 Root CA 憑證:從 API 下載 CA 憑證(
/api/v1/ca/1) - 驗證憑證格式:使用
openssl x509檢查憑證結構 - 驗證自簽憑證:使用
openssl verify驗證 Root CA 自簽有效性 - 產生 CSR:使用
openssl req產生測試用 CSR - 使用 NG-CA 簽發憑證:呼叫 API 端點(
POST /api/v1/ca/1/issue)簽發憑證 - 驗證憑證鏈:使用 OpenSSL 驗證憑證鏈完整性
- 檢查混合憑證延伸:確認 PQC 延伸欄位存在(OID 2.5.29.72/73/74)
驗證結果:
- Root CA 自簽驗證通過
- 憑證鏈驗證通過(OpenSSL 相容)
- 混合憑證延伸欄位正確(Subject Alt Public Key Info、Alt Signature Algorithm、Alt Signature Value)
未來發展
SLH-DSA / FN-DSA HSM 化
目標時程:跟隨 Luna 韌體 roadmap(Thales 預計 2026-2027 上線)
主要工作項目:
- 等待 Luna 釋出
CKM_SLH_DSA_*與CKM_FN_DSA_*mechanism - 在
luna-cryptokicrate 補上對應 wrapper - 把
SlhDsaProvider/FnDsaProvider改為 dispatch(軟體 fallback + HSM 優先) - 應用層完全無感(
KeyMaterial::Software→HsmLabel自動切換)
CA/B Forum TLS BR PQC 對齊
目標時程:跟隨 CA/B Forum 投票時程(預計 2026-2027)
關鍵未定點:
- 公開 TLS 簽發是否允許 hybrid(vs. pure PQC)
- ML-DSA-44 vs ML-DSA-65 vs ML-DSA-87 的選用基準
- 憑證鏈總大小上限(影響 OCSP stapling 必要性)
NG-CA 準備:composite OID 已實作完成,但暫不開放公開 TLS 簽發;私有 CA 與 S/MIME 場景已可用。
gRPC API
動機:支援微服務架構與高效能 RPC
API 設計(proto/ca.proto):
syntax = "proto3";
package ng_ca.v1;
service CaService {
rpc CreateCa(CreateCaRequest) returns (CreateCaResponse);
rpc IssueCertificate(IssueCertificateRequest) returns (IssueCertificateResponse);
rpc RevokeCertificate(RevokeCertificateRequest) returns (RevokeCertificateResponse);
rpc GetCRL(GetCRLRequest) returns (GetCRLResponse);
}
message CreateCaRequest {
string name = 1;
Algorithm algorithm = 2;
bool is_ca = 3;
optional uint32 path_len = 4;
uint32 default_days = 5;
}
enum Algorithm {
ALGORITHM_UNSPECIFIED = 0;
RSA_2048 = 1;
RSA_3072 = 2;
RSA_4096 = 3;
ECC_P256 = 4;
ECC_P384 = 5;
ECC_P521 = 6;
ML_DSA_44 = 7;
ML_DSA_65 = 8;
ML_DSA_87 = 9;
HYBRID = 10;
}
message CreateCaResponse {
int64 ca_id = 1;
string certificate_pem = 2;
}
message IssueCertificateRequest {
int64 ca_id = 1;
string csr_pem = 2;
uint32 days = 3;
bool is_ca = 4;
optional uint32 path_len = 5;
}
message IssueCertificateResponse {
string serial_number = 1;
string certificate_pem = 2;
}
多租戶支援
資料隔離設計:
-- 新增租戶表
CREATE TABLE tenants (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
api_key TEXT NOT NULL UNIQUE,
created_at TEXT DEFAULT (datetime('now'))
);
-- CA 表添加租戶關聯
ALTER TABLE cas ADD COLUMN tenant_id INTEGER REFERENCES tenants(id);
-- 憑證表添加租戶關聯
ALTER TABLE certificates ADD COLUMN tenant_id INTEGER REFERENCES tenants(id);
-- Row-Level Security
CREATE INDEX idx_ca_tenant ON cas(tenant_id);
CREATE INDEX idx_cert_tenant ON certificates(tenant_id);
API 認證邏輯(tenant_auth_middleware):
驗證流程:
- 提取 API Key:從請求標頭
X-API-Key取得金鑰 - 查詢租戶:使用 API Key 從
tenants表查詢對應的租戶 - 權限驗證:若 API Key 不存在或無效,回傳
401 Unauthorized - 注入租戶 ID:將租戶 ID 注入請求延伸(
req.extensions_mut()) - 繼續處理:將請求傳遞給下一個 middleware 或 handler
資料隔離:所有 CA 與憑證查詢自動過濾 tenant_id,確保租戶間資料完全隔離
結語與資源
關鍵要點
- 兩種 hybrid 模式並存:對齊 RFC 9794 —
Algorithm::Hybrid(non-composite,向下相容)+Algorithm::HybridDualSignature(composite,draft-ietf-lamps-pq-composite-sigs-19) - 18 個演算法、5 大類別:RSA / ECC / ML-DSA / SLH-DSA / FN-DSA / ML-KEM 全套,從 FIPS 186-5 到 FIPS 203/204/205
- Luna HSM 託管金鑰:Pure Rust 應用層 + Luna FIPS 140-3 Level 3 硬體,私鑰永不離開 HSM;KeyMaterial enum 在型別系統強制區分
- 企業級功能完備:Prometheus 監控(25+ 指標)、Name Constraints、Delta CRL、verify-chain API、moka cache
- ACME v2 + JWS:RFC 8555 完整流程,ES256 / RS256 簽章驗證
- 台灣在地化:身份證 / 統編 / 組織機構代碼驗證
- 生產就緒:71/71 測試通過(100%)、v1.0 Released
專案資源
核心標準:
- FIPS 203 (ML-KEM) · FIPS 204 (ML-DSA) · FIPS 205 (SLH-DSA)
- RFC 9794 — PQ/Traditional Hybrid Terminology(2025-06)
- RFC 9881 — X.509 ML-DSA(2025-10)· RFC 9909 — X.509 SLH-DSA(2025-12)
- draft-ietf-lamps-pq-composite-sigs-19(NG-CA
HybridDualSignature對齊版本) - RFC 8555 (ACME v2) · RFC 6960 (OCSP) · RFC 5280 (X.509 / CRL / 路徑驗證)
部署參考:
- Cloudflare PQC 2025 Report(50%+ 流量已 hybrid)
- BSI Migration to PQC
- PKCS#11 v3.0(Luna HSM mechanism 參考)
雲杉相關文章:
- Luna HSM × Prometheus 監控(這篇講金鑰運維面)
- PQC × Rust × Luna HSM 企業級方案
- cbom_scanner — 用 CycloneDX 1.6 盤點密碼學資產(PQC 遷移前的盤點工具)
- Code Signing 憑證縮短至 460 天 — PKI 產業趨勢(TLS 也走向 398→47 天;NG-CA 的 ACME v2 自動化是同一趨勢的解法)
本文最初發表於 2026-02-04,於 2026-05-10 全面更新:對齊 RFC 9794(hybrid 術語)、新增 Luna HSM Phase A-C 整合、新增 SLH-DSA / FN-DSA / ML-KEM 演算法支援、Algorithm::HybridDualSignature (composite-sigs draft-19) 雙模式並存、NG-CA v1.0 Released(71/71 測試通過)。
如有任何問題或建議,歡迎透過聯絡我們 頁面與我們聯繫。