CA Backup/Restore

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.


Backup Components

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

Backup Strategy

flowchart TB subgraph LIVE["PRODUCTION"] L1[CA Server] L2[HSM] end subgraph BACKUP["BACKUP"] B1[Encrypted Backup] B2[HSM Backup Slot] B3[Shamir Shares] end subgraph OFFLINE["OFFLINE"] O1[Safe] O2[Custodians] O3[Off-Site] end L1 --> B1 --> O1 L2 --> B2 --> O3 L1 --> B3 --> O2 style L2 fill:#e8f5e9 style O1 fill:#e3f2fd


Backup Procedures

Software Keys (without HSM)

#!/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"

HSM-based Keys

#!/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>

Shamir Secret Sharing

#!/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"

Restore Procedures

Software Keys

#!/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 ==="

Combine Shamir Shares

#!/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

Backup Verification

#!/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 ==="

Backup Schedule

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

Checklist

# 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

Zuletzt geändert: on 2026/01/30 at 01:29 AM