====== Parallel Operation ====== **Complexity:** Medium \\ **Duration:** Unlimited (until classic deactivated) \\ **Risk:** Low Simultaneous operation of classic and post-quantum PKI for maximum compatibility. ---- ===== Architecture ===== flowchart TB subgraph CLASSIC["CLASSIC PKI"] CR[Classic Root CA] CI[Classic Intermediate] CC[Classic Certificates] end subgraph HYBRID["HYBRID PKI"] HR[Hybrid Root CA] HI[Hybrid Intermediate] HC[Hybrid Certificates] end subgraph CLIENTS["CLIENTS"] OLD[Legacy Clients] NEW[Modern Clients] end CR --> CI --> CC HR --> HI --> HC CC --> OLD HC --> NEW CC -.->|Fallback| NEW style CLASSIC fill:#ffebee style HYBRID fill:#e8f5e9 ---- ===== When Parallel Operation? ===== | Scenario | Recommendation | |----------|----------------| | Legacy systems not updatable | Parallel | | Gradual migration over years | Parallel | | Regulatory requirements for backward compatibility | Parallel | | Greenfield / New project | Direct Hybrid | | All clients updatable | Hybrid migration | ---- ===== Setup ===== ==== Directory Structure ==== /etc/pki/ +-- classic/ | +-- root-ca.pem | +-- intermediate-ca.pem | +-- intermediate-ca.key | +-- crl/ | +-- issued/ +-- hybrid/ | +-- root-ca.pem | +-- intermediate-ca.pem | +-- intermediate-ca.key | +-- crl/ | +-- issued/ +-- scripts/ +-- issue-classic.sh +-- issue-hybrid.sh +-- issue-both.sh ==== Dual-Issue Script ==== #!/bin/bash # /etc/pki/scripts/issue-both.sh # Issues a certificate from BOTH PKIs CSR_FILE="$1" OUTPUT_PREFIX="$2" if [ -z "$CSR_FILE" ] || [ -z "$OUTPUT_PREFIX" ]; then echo "Usage: $0 " exit 1 fi # Issue classic certificate echo "Issuing classic certificate..." openssl ca -config /etc/pki/classic/openssl.cnf \ -in "$CSR_FILE" \ -out "${OUTPUT_PREFIX}-classic.pem" \ -days 365 \ -batch # Issue hybrid certificate echo "Issuing hybrid certificate..." /usr/local/bin/wvds-sign --mode hybrid \ --ca /etc/pki/hybrid/intermediate-ca.pfx \ --csr "$CSR_FILE" \ --out "${OUTPUT_PREFIX}-hybrid.pem" \ --days 365 echo "Done:" echo " Classic: ${OUTPUT_PREFIX}-classic.pem" echo " Hybrid: ${OUTPUT_PREFIX}-hybrid.pem" ---- ===== Server Configuration ===== ==== Nginx: Dual Certificate ==== server { listen 443 ssl; server_name api.example.com; # Primary: Hybrid certificate ssl_certificate /etc/ssl/certs/api-hybrid.pem; ssl_certificate_key /etc/ssl/private/api.key; # Fallback: Classic certificate (for old clients) # Note: Nginx supports only one certificate per server block # For true dual-mode: Separate server blocks or SNI } # Alternative: Separate server for legacy server { listen 443 ssl; server_name api-legacy.example.com; ssl_certificate /etc/ssl/certs/api-classic.pem; ssl_certificate_key /etc/ssl/private/api.key; } ==== Apache: Dual Certificate ==== ServerName api.example.com # Modern clients -> Hybrid SSLCertificateFile /etc/ssl/certs/api-hybrid.pem SSLCertificateKeyFile /etc/ssl/private/api.key SSLCertificateChainFile /etc/ssl/certs/hybrid-chain.pem ServerName api-legacy.example.com # Legacy clients -> Classic SSLCertificateFile /etc/ssl/certs/api-classic.pem SSLCertificateKeyFile /etc/ssl/private/api.key SSLCertificateChainFile /etc/ssl/certs/classic-chain.pem ---- ===== Trust Store Management ===== ==== Clients with Both CAs ==== # Trust store with both root CAs cat /etc/pki/classic/root-ca.pem /etc/pki/hybrid/root-ca.pem > /etc/ssl/certs/ca-bundle.pem # Or add individually update-ca-trust extract ==== Windows Trust Store ==== # Import both root CAs Import-Certificate -FilePath "classic-root.cer" -CertStoreLocation Cert:\LocalMachine\Root Import-Certificate -FilePath "hybrid-root.cer" -CertStoreLocation Cert:\LocalMachine\Root ---- ===== CRL/OCSP for Both PKIs ===== # CRL Distribution Points # Classic: http://crl.example.com/classic/intermediate.crl # Hybrid: http://crl.example.com/hybrid/intermediate.crl # Nginx for CRL distribution location /crl/classic/ { alias /etc/pki/classic/crl/; types { application/pkix-crl crl; } } location /crl/hybrid/ { alias /etc/pki/hybrid/crl/; types { application/pkix-crl crl; } } ---- ===== Monitoring ===== # Prometheus: Monitor both PKIs scrape_configs: - job_name: 'pki-classic' static_configs: - targets: ['localhost:9793'] params: path: ['/etc/pki/classic/issued/*.pem'] relabel_configs: - target_label: pki replacement: 'classic' - job_name: 'pki-hybrid' static_configs: - targets: ['localhost:9793'] params: path: ['/etc/pki/hybrid/issued/*.pem'] relabel_configs: - target_label: pki replacement: 'hybrid' **Dashboard Metrics:** | Metric | Classic | Hybrid | |--------|---------|--------| | Active certificates | ''count(x509{pki="classic"})'' | ''count(x509{pki="hybrid"})'' | | Expiring < 30d | ''count(...)'' | ''count(...)'' | | CRL Next Update | ''crl_next_update{pki="classic"}'' | ''crl_next_update{pki="hybrid"}'' | ---- ===== Migration Tracking ===== #!/bin/bash # migration-status.sh - Migration progress echo "=== PKI Migration Status ===" classic_count=$(find /etc/pki/classic/issued -name "*.pem" | wc -l) hybrid_count=$(find /etc/pki/hybrid/issued -name "*.pem" | wc -l) total=$((classic_count + hybrid_count)) if [ "$total" -gt 0 ]; then hybrid_percent=$((hybrid_count * 100 / total)) else hybrid_percent=0 fi echo "Classic: $classic_count" echo "Hybrid: $hybrid_count" echo "Total: $total" echo "Migration: $hybrid_percent%" # Graphical representation echo "" echo -n "Progress: [" for i in $(seq 1 50); do if [ $i -le $((hybrid_percent / 2)) ]; then echo -n "#" else echo -n "-" fi done echo "] $hybrid_percent%" ---- ===== Phase-Out Classic ===== flowchart LR subgraph ACTIVE["ACTIVE"] A1[Both PKIs active] end subgraph TRANSITION["TRANSITION"] T1[Classic: renewal only] T2[Hybrid: new certificates] end subgraph SUNSET["SUNSET"] S1[Classic: still active only] S2[No new classic certs] end subgraph END["END"] E1[Classic deactivated] end ACTIVE --> TRANSITION --> SUNSET --> END style ACTIVE fill:#e8f5e9 style END fill:#ffebee **Timeline:** | Phase | Action | Trigger | |-------|--------|---------| | Active | Both PKIs issuing | Start | | Transition | Classic renewal only | 80% Hybrid | | Sunset | Classic only expire | 95% Hybrid | | End | Classic CA offline | All classic expired | ---- ===== Checklist ===== | # | Checkpoint | Done | |---|------------|------| | 1 | Both PKIs set up | | | 2 | Dual-issue scripts work | | | 3 | Trust stores contain both CAs | | | 4 | CRL/OCSP available for both | | | 5 | Monitoring active for both | | | 6 | Migration tracking set up | | | 7 | Phase-out plan documented | | ---- ===== Related Documentation ===== * [[.:classic-to-hybrid|Classic -> Hybrid]] - Direct migration * [[.:rollback-strategie|Rollback Strategy]] - Emergency plan * [[..:monitoring:start|Monitoring]] - Monitor both PKIs ---- << [[.:classic-to-hybrid|<- Classic -> Hybrid]] | [[.:rollback-strategie|-> Rollback Strategy]] >> ---- //Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional// {{tag>migration parallel dual-pki compatibility operator}}