Scenario 11.3: Key Rotation
Category: Key Management
Complexity: ⭐⭐⭐⭐ (High)
Prerequisites: Existing keys, backup strategy
Estimated Time: 30-45 Minutes
Description
This scenario describes the regular rotation of cryptographic keys. Key rotation is a critical security measure that limits the risk of compromise.
Rotation Reasons:
- Time-based - Maximum key lifetime reached
- Usage-based - Maximum operations/data volume
- Security Incident - Suspicion of compromise
- Compliance - Regulatory requirements
- Algorithm Upgrade - Migration to stronger algorithms
Workflow
flowchart TD
TRIGGER[Rotation Trigger] --> CHECK{Rotation needed?}
CHECK -->|No| WAIT[Wait]
CHECK -->|Yes| BACKUP[Backup old key]
BACKUP --> GEN[Generate new key]
GEN --> MIGRATE[Migrate systems]
MIGRATE --> TEST[Function test]
TEST --> OVERLAP{Overlap OK?}
OVERLAP -->|Yes| RETIRE[Deactivate old key]
OVERLAP -->|No| ROLLBACK[Rollback]
RETIRE --> ARCHIVE[Archive/Delete]
style GEN fill:#e8f5e9
style BACKUP fill:#fff3e0
Code Example: Automatic Rotation
using WvdS.Security.Cryptography.X509Certificates.Extensions.PQ; public class KeyRotationService { private readonly IKeyStore _keyStore; private readonly TimeSpan _maxKeyAge = TimeSpan.FromDays(365); private readonly long _maxOperations = 1_000_000; public KeyRotationService(IKeyStore keyStore) { _keyStore = keyStore; } public async Task<RotationResult> CheckAndRotateAsync(string keyId) { var metadata = await _keyStore.GetMetadataAsync(keyId); // Check rotation conditions var needsRotation = ShouldRotate(metadata); if (!needsRotation.Required) { return new RotationResult { KeyId = keyId, Rotated = false, Reason = "No rotation required" }; } return await PerformRotationAsync(keyId, metadata, needsRotation.Reason); } private RotationCheck ShouldRotate(KeyMetadata metadata) { // 1. Time-based rotation if (DateTime.UtcNow - metadata.CreatedAt > _maxKeyAge) { return new RotationCheck(true, "Maximum age reached"); } // 2. Usage-based rotation if (metadata.OperationCount > _maxOperations) { return new RotationCheck(true, "Maximum operations reached"); } // 3. Algorithm upgrade (RSA → ML-DSA) if (metadata.Algorithm.StartsWith("RSA") && !metadata.Algorithm.Contains("ML-DSA")) { return new RotationCheck(true, "PQ migration required"); } return new RotationCheck(false, null); } private async Task<RotationResult> PerformRotationAsync( string keyId, KeyMetadata oldMetadata, string reason) { using var ctx = PqCryptoContext.Initialize(); // 1. Backup old key await _keyStore.BackupAsync(keyId); // 2. Generate new key var newKeyId = $"{keyId}-{DateTime.UtcNow:yyyyMMdd}"; using var newKey = ctx.GenerateKeyPair(PqAlgorithm.MlDsa65); // 3. Store new key await _keyStore.StoreAsync(newKeyId, newKey, new KeyMetadata { Algorithm = "ML-DSA-65", CreatedAt = DateTime.UtcNow, PreviousKeyId = keyId, RotationReason = reason }); // 4. Mark old key as "rotating" await _keyStore.SetStatusAsync(keyId, KeyStatus.Rotating); return new RotationResult { KeyId = keyId, NewKeyId = newKeyId, Rotated = true, Reason = reason }; } }
Code Example: Overlap Phase
public class OverlappingKeyManager { public async Task<byte[]> SignWithOverlap( byte[] data, string keyId, IKeyStore keyStore) { using var ctx = PqCryptoContext.Initialize(); // Load current key var currentKey = await keyStore.GetCurrentKeyAsync(keyId); // Sign with current key var signature = ctx.SignData( data, currentKey, HashAlgorithmName.SHA256 ); return signature; } public async Task<bool> VerifyWithOverlap( byte[] data, byte[] signature, string keyId, IKeyStore keyStore) { using var ctx = PqCryptoContext.Initialize(); // Get all valid key versions var validKeys = await keyStore.GetValidKeysAsync(keyId); foreach (var key in validKeys) { try { if (ctx.VerifyData(data, signature, key.PublicKey, HashAlgorithmName.SHA256)) { return true; } } catch (CryptographicException) { // Wrong key, try next continue; } } return false; } }
Rotation Policies
| Key Type | Maximum Age | Maximum Operations | Overlap |
|---|---|---|---|
| Root CA Key | 10-20 years | N/A | 1 year |
| Intermediate CA Key | 3-5 years | N/A | 90 days |
| TLS Server Key | 1 year | 10M handshakes | 7 days |
| Code Signing Key | 2 years | 100K signatures | 30 days |
| Encryption Key | 1 year | 100TB data | 30 days |
Industry-Specific Rotation Requirements
| Industry | Rotation Cycle | Requirement | Specifics |
|---|---|---|---|
| Financial Sector | 1 year | PCI-DSS 3.6.4 | Audit trail mandatory |
| Healthcare | 2 years | HIPAA | Key escrow |
| Energy/KRITIS | 3 years | BSI KRITIS-VO | Maintenance window |
| Government | 2 years | BSI TR-03116 | HSM mandatory |
Related Scenarios
| Relationship | Scenario | Description |
|---|---|---|
| Prerequisite | 11.2 Key Storage | Secure storage |
| Prerequisite | 11.4 Key Backup | Backup before rotation |
| Next Step | 11.5 Key Destruction | Delete old keys |
| Related | 4.2 Rekey | Certificate with new key |
« ← 11.2 Key Storage | ↑ Key Overview | 11.4 Key Backup → »
Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional
Zuletzt geändert: on 2026/01/30 at 06:42 AM