Critical: CA keys are the most valuable asset of the PKI!
RTO: 4 hours | RPO: 24 hours
Procedures for backing up and restoring CA keys and certificates.
| Component | Criticality | Backup Frequency |
| ———– | ————- | —————— |
| Root CA Private Key | Critical | Once + Offline |
| Intermediate Private Keys | High | After each change |
| CA Certificates | Medium | Daily |
| CA Database (index.txt) | Medium | Daily |
| Configuration (openssl.cnf) | Low | On change |
| CRL Signing Key | High | With CA Key |
#!/bin/bash # ca-backup.sh - Create CA backup BACKUP_DIR="/backup/pki/$(date +%Y%m%d)" ENCRYPTION_KEY="/etc/pki/backup-key.pem" # RSA public key for encryption mkdir -p "$BACKUP_DIR" # 1. Private keys (encrypted) echo "Backing up private keys..." for key in /etc/pki/CA/*.key; do keyname=$(basename "$key" .key) # Encrypt with AES-256 openssl enc -aes-256-cbc -salt -pbkdf2 \ -in "$key" \ -out "$BACKUP_DIR/${keyname}.key.enc" \ -pass file:/etc/pki/backup-passphrase.txt # Or with RSA public key (asymmetric) openssl pkeyutl -encrypt \ -pubin -inkey "$ENCRYPTION_KEY" \ -in "$key" \ -out "$BACKUP_DIR/${keyname}.key.rsa-enc" done # 2. Certificates echo "Backing up certificates..." cp /etc/pki/CA/*.pem "$BACKUP_DIR/" # 3. CA database echo "Backing up CA database..." cp /etc/pki/CA/index.txt "$BACKUP_DIR/" cp /etc/pki/CA/serial "$BACKUP_DIR/" cp /etc/pki/CA/crlnumber "$BACKUP_DIR/" # 4. Configuration cp /etc/pki/CA/openssl.cnf "$BACKUP_DIR/" # 5. Issued certificates tar czf "$BACKUP_DIR/issued-certs.tar.gz" /etc/pki/CA/newcerts/ # 6. Checksums cd "$BACKUP_DIR" sha256sum * > SHA256SUMS # 7. Full archive (optional) cd /backup/pki tar czf "ca-backup-$(date +%Y%m%d).tar.gz" "$(date +%Y%m%d)/" echo "Backup completed: $BACKUP_DIR"
#!/bin/bash # hsm-backup.sh - HSM key backup # Luna HSM /usr/safenet/lunaclient/bin/lunacm << EOF partition backup partition name = ca-partition backup file = /backup/hsm/ca-partition-$(date +%Y%m%d).bak EOF # Thales HSM nShield-cknfastrc backup --slotlist=0 --output=/backup/hsm/nshield-$(date +%Y%m%d).bak # AWS CloudHSM aws cloudhsmv2 create-cluster-backup --cluster-id <cluster-id>
#!/bin/bash # shamir-split.sh - Distribute key to custodians KEY_FILE="/etc/pki/CA/root-ca.key" SHARES=5 THRESHOLD=3 # With ssss-split (Shamir's Secret Sharing Scheme) cat "$KEY_FILE" | ssss-split -t $THRESHOLD -n $SHARES -w root-ca # Result: 5 files (root-ca-1 to root-ca-5) # At least 3 are needed for recovery # Distribute to custodians echo "Distribute shares to custodians:" echo " Share 1 -> Custodian A" echo " Share 2 -> Custodian B" echo " Share 3 -> Custodian C" echo " Share 4 -> Off-site safe" echo " Share 5 -> HSM escrow"
#!/bin/bash # ca-restore.sh - Restore CA from backup BACKUP_FILE="$1" RESTORE_DIR="/etc/pki/CA" if [ -z "$BACKUP_FILE" ]; then echo "Usage: $0 <backup-file.tar.gz>" exit 1 fi echo "=== CA RESTORE ===" echo "Backup: $BACKUP_FILE" read -p "Continue? (yes/no): " confirm [ "$confirm" != "yes" ] && exit 1 # 1. Back up current state echo "Backing up current state..." mv "$RESTORE_DIR" "${RESTORE_DIR}.pre-restore-$(date +%Y%m%d%H%M%S)" # 2. Extract backup echo "Extracting backup..." mkdir -p "$RESTORE_DIR" tar xzf "$BACKUP_FILE" -C "$RESTORE_DIR" --strip-components=1 # 3. Decrypt private keys echo "Decrypting private keys..." for enc_key in "$RESTORE_DIR"/*.key.enc; do keyname=$(basename "$enc_key" .key.enc) openssl enc -aes-256-cbc -d -pbkdf2 \ -in "$enc_key" \ -out "$RESTORE_DIR/${keyname}.key" \ -pass file:/etc/pki/backup-passphrase.txt rm "$enc_key" done # 4. Set permissions chmod 600 "$RESTORE_DIR"/*.key chmod 644 "$RESTORE_DIR"/*.pem chown -R root:root "$RESTORE_DIR" # 5. Verify echo "Verifying restoration..." for key in "$RESTORE_DIR"/*.key; do cert="${key%.key}.pem" if [ -f "$cert" ]; then key_mod=$(openssl rsa -in "$key" -noout -modulus 2>/dev/null | md5sum) cert_mod=$(openssl x509 -in "$cert" -noout -modulus 2>/dev/null | md5sum) if [ "$key_mod" = "$cert_mod" ]; then echo "OK $(basename "$key"): Key/Cert match" else echo "ERROR $(basename "$key"): MISMATCH!" fi fi done # 6. Start CA services echo "Starting CA services..." systemctl start pki-ca systemctl start ocsp-responder echo "=== RESTORE COMPLETED ==="
#!/bin/bash # shamir-combine.sh - Restore key from shares echo "Shamir Share Recovery" echo "At least 3 of 5 shares required" # Collect shares (from custodians) ssss-combine -t 3 > /tmp/restored-key.tmp << EOF <Share-1-from-Custodian-A> <Share-2-from-Custodian-B> <Share-3-from-Custodian-C> EOF # Verify openssl rsa -in /tmp/restored-key.tmp -check -noout if [ $? -eq 0 ]; then echo "Key successfully restored" mv /tmp/restored-key.tmp /etc/pki/CA/root-ca.key chmod 600 /etc/pki/CA/root-ca.key else echo "ERROR: Key invalid!" rm /tmp/restored-key.tmp fi
#!/bin/bash # verify-backup.sh - Verify backup integrity BACKUP_DIR="$1" echo "=== Backup Verification ===" # Verify checksums cd "$BACKUP_DIR" sha256sum -c SHA256SUMS if [ $? -ne 0 ]; then echo "ERROR: Checksum mismatch!" exit 1 fi # Verify key/cert pairs for enc_key in *.key.enc; do keyname=$(basename "$enc_key" .key.enc) cert="${keyname}.pem" if [ ! -f "$cert" ]; then echo "WARNING: No certificate for $keyname" continue fi # Decrypt and verify (temporarily) openssl enc -aes-256-cbc -d -pbkdf2 \ -in "$enc_key" \ -out /tmp/verify.key \ -pass file:/etc/pki/backup-passphrase.txt key_mod=$(openssl rsa -in /tmp/verify.key -noout -modulus 2>/dev/null | md5sum) cert_mod=$(openssl x509 -in "$cert" -noout -modulus 2>/dev/null | md5sum) if [ "$key_mod" = "$cert_mod" ]; then echo "OK $keyname: OK" else echo "ERROR $keyname: MISMATCH!" fi rm /tmp/verify.key done echo "=== Verification completed ==="
| Component | Frequency | Retention | Medium |
| ———– | ———– | ———– | ——– |
| CA Database | Daily | 30 days | Disk → Tape |
| Intermediate Keys | Weekly | 1 year | Encrypted Disk |
| Root CA Key | Once | Permanent | Offline Safe |
| Configuration | On change | 5 versions | Git |
| # | Checkpoint | Done |
| — | ———— | —— |
| 1 | Backup script configured | |
| 2 | Encryption key securely stored | |
| 3 | Shamir shares distributed | |
| 4 | Backup cron active | |
| 5 | Off-site backup available | |
| 6 | Restore test successful | |
| 7 | Last verification < 30 days |
« <- Disaster Recovery | -> Key Ceremony »
Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional