Service Info

Status--
Endpointhttp://docker:8083
PQC AlgorithmML-DSA-65
FIPS StandardFIPS 204 (ML-DSA)

Where PQC is Used

📄
Root CA

Self-signed root of trust with ML-DSA-65. 10-year validity. Foundation of the PQC PKI hierarchy.

ML-DSA-65
🔗
Intermediate CA

Signed by Root CA. Issues end-entity certificates. 5-year validity. Keeps root key offline.

ML-DSA-65
💻
End-Entity Certificates

Server/client certificates signed by Intermediate CA. 1-year validity. For TLS, mTLS, code signing.

ML-DSA-65
🔀
Hybrid Certificates

Dual ECDSA P-384 + ML-DSA-65 certificates for backward compatibility during PQC migration.

ECDSA + ML-DSA-65

Description

This service demonstrates a full PQC PKI hierarchy — the same patterns you'll implement using the Qudo JNI provider in your own certificate infrastructure.

Key generation: provider.generateKeyPair("ML-DSA-65")
Self-signed cert: provider.createSelfSignedCert(privKey, subject, days)
CSR + signing: provider.createCSR(privKey, subject) then provider.signCSR(csr, caKey, caCert, days)

Root CA → Intermediate CA → End-Entity certificates. Hybrid certificates (ECDSA + PQC) for backward compatibility.

POST /api/ca/create-root Create a PQC Root CA
🔒 Qudo provider: provider.generateKeyPair("ML-DSA-65") + provider.createSelfSignedCert(). Returns PEM cert + parsed details.
POST /api/ca/create-intermediate Create Intermediate CA (signed by Root)
🔒 Qudo provider: provider.createCSR() + provider.signCSR(csr, rootKey, rootCert). Proper chain: Root -> Intermediate.
POST /api/ca/issue-cert Issue end-entity certificate
🔒 Qudo provider: provider.createCSR() + provider.signCSR(). Full chain: Root -> Intermediate -> End Entity.
POST /api/ca/create-hybrid Create hybrid certificate (ECDSA + PQC)
🔒 Qudo provider: generates both ECDSA P-384 and ML-DSA-65 keypairs + self-signed certs. For backward-compatible migration.
GET /api/ca/chain View all issued certificates
🔒 Lists all Root, Intermediate, and End-Entity certificates with metadata.
GET /api/ca/health Service health + supported algorithms
🔒 Returns service status and ML-DSA algorithms available for certificate signing.

CA Service Migration Reference

Migrate your PKI from classical RSA/ECDSA to post-quantum ML-DSA-65 certificates. Use this playground to try PQC certificate operations, then use the Qudo JNI provider in your own PKI infrastructure.

1. PKI Overview 2. Migrate Your PKI 3. Classical vs PQC 4. Performance 5. FAQ

1. PQC PKI Overview

A standard PKI hierarchy with quantum-safe certificates:

Root CA (ML-DSA-65, self-signed, 10-year validity)
  |
  +-- Intermediate CA (ML-DSA-65, signed by Root, 5-year validity)
        |
        +-- Server Cert (ML-DSA-65, signed by Intermediate, 1-year validity)
        +-- Client Cert (ML-DSA-65, signed by Intermediate, 1-year validity)
        +-- Code Signing Cert (ML-DSA-65, signed by Intermediate, 1-year validity)
🔒
Same PKI model

The hierarchy, trust chain, and X.509 format are identical to classical PKI. Only the signature algorithm inside the certificate changes from RSA/ECDSA to ML-DSA-65.

🔄
Hybrid mode available

Issue both ECDSA and ML-DSA-65 certificates for the same subject during migration. Clients use whichever they support.

2. Migrate Your PKI

Replace your classical RSA/ECDSA certificate generation with the Qudo JNI provider. The PKI hierarchy pattern stays the same.

import com.qudo.crypto.QudoCrypto;
import com.qudo.crypto.QudoKeyPair;

QudoCrypto provider = QudoCrypto.create();

// ============================================================
// 1. Create Root CA (self-signed, 10-year validity)
// ============================================================
QudoKeyPair rootKeys = provider.generateKeyPair("ML-DSA-65");
byte[] rootCert = provider.createSelfSignedCert(
    rootKeys.getPrivateKeyPem(),
    "/CN=My Organization Root CA/O=My Org/C=US", 3650);
// Store rootKeys.getPrivateKeyPem() OFFLINE (HSM)
// Distribute rootCert as trust anchor

// ============================================================
// 2. Create Intermediate CA (signed by Root, 5-year validity)
// ============================================================
QudoKeyPair intermediateKeys = provider.generateKeyPair("ML-DSA-65");
byte[] intermediateCSR = provider.createCSR(
    intermediateKeys.getPrivateKeyPem(),
    "/CN=My Intermediate CA/O=My Org/OU=PKI/C=US");
byte[] intermediateCert = provider.signCSR(
    intermediateCSR, rootKeys.getPrivateKeyPem(), rootCert, 1825);

// ============================================================
// 3. Issue End-Entity Certificate (1-year validity)
// ============================================================
QudoKeyPair serverKeys = provider.generateKeyPair("ML-DSA-65");
byte[] serverCSR = provider.createCSR(
    serverKeys.getPrivateKeyPem(),
    "/CN=api.example.com/O=My Org/C=US");
byte[] serverCert = provider.signCSR(
    serverCSR, intermediateKeys.getPrivateKeyPem(), intermediateCert, 365);

// ============================================================
// 4. Verify the chain (openssl CLI)
// ============================================================
// cat intermediate.crt root-ca.crt > ca-chain.crt
// openssl verify -CAfile ca-chain.crt server.crt
// Expected: server.crt: OK
// openssl x509 -in server.crt -noout -text | grep "Signature Algorithm"
// Shows: Signature Algorithm: ML-DSA-65

provider.close();
This is what runs in your PKI system. The Qudo JNI provider handles key generation, CSR creation, and certificate signing natively. The resulting PEM certificates are standard X.509 — compatible with NGINX, Apache, and any TLS stack that supports ML-DSA.

3. Migrate from Classical PKI

Classical PKI

# RSA Root CA
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096
openssl req -new -x509 -key root.key -sha256 ...

# ECDSA Intermediate
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-384
openssl req -new -key intermediate.key ...

PQC PKI (via Qudo)

# ML-DSA-65 Root CA
openssl genpkey -algorithm ML-DSA-65
openssl req -new -x509 -key root.key ...

# ML-DSA-65 Intermediate (same commands)
openssl genpkey -algorithm ML-DSA-65
openssl req -new -key intermediate.key ...
ComponentChanges?Details
X.509 formatNoSame ASN.1 structure, same extensions, same chain model
Key algorithmYesRSA/ECDSA → ML-DSA-65 (one flag change in openssl genpkey)
Signature algorithmYesSHA256withRSA/ECDSA → ML-DSA-65 (automatic from key type)
Certificate sizeYes~10KB for ML-DSA-65 vs ~1-2KB for RSA/ECDSA (public key is larger)
Chain validationNoSame openssl verify command, same trust model
OCSP / CRLNoSame revocation mechanisms
OpenSSL commandsMinimalReplace -algorithm RSA with -algorithm ML-DSA-65

4. Performance

OperationML-DSA-65RSA-4096ECDSA P-384
Key generation~55ms~500ms~5ms
Certificate signing~120ms~50ms~5ms
Certificate verification~40ms~1ms~2ms
Certificate size~10KB~2KB~1KB
Public key size~2.7KB~512B~91B
Impact: Certificate issuance is slower but happens infrequently (once per server/service). Verification is the frequent operation (~40ms) and is acceptable for TLS handshakes with session reuse.

5. FAQ

Q: Can I use ML-DSA-65 certificates with existing TLS servers?

A: The server (NGINX, Apache) must be built with OpenSSL 3.6+ and the Qudo Cryptographic Module. Standard NGINX with older OpenSSL will reject ML-DSA-65 certificates. During migration, use hybrid mode — serve ECDSA certs to classical clients and ML-DSA-65 certs to PQC-capable clients.

Q: Are ML-DSA-65 certificates compatible with browsers?

A: Browser support for PQC certificates is still emerging. Chrome and Firefox support PQC key exchange (X25519MLKEM768) but not PQC certificates for server authentication yet. Use ECDSA certificates for TLS server auth and ML-DSA-65 for code signing, internal mTLS, and non-browser use cases.

Q: Should I re-issue all my certificates?

A: Not immediately. Start with new certificates — issue ML-DSA-65 certs for new services. Existing certificates can remain ECDSA until they expire. Prioritize code signing and internal mTLS certificates where you control both endpoints.

Q: How do hybrid certificates work?

A: The hybrid endpoint creates two separate certificates — one ECDSA P-384 and one ML-DSA-65 — for the same subject. The server presents the appropriate certificate based on what the client supports. This isn't a composite certificate; it's dual-stack PKI.

Q: Certificate size is 10KB — does that matter?

A: For most use cases, no. TLS handshakes transmit the full chain (~30KB for a 3-cert chain) which adds ~1 RTT. With TLS session resumption, this cost is paid only once. For constrained environments (IoT with limited bandwidth), consider ML-DSA-44 which produces smaller certs.

Crypto Inventory Scanner

Analyze any endpoint's cryptographic configuration. Enter a host:port to scan its TLS setup and identify what's quantum-safe vs what needs migration.

Scan Endpoint