~~NOTOC~~
====== Scenario 11.3: Key Rotation ======
**Category:** [[.:start|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 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 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 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 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** | [[.:speicherung|11.2 Key Storage]] | Secure storage |
| **Prerequisite** | [[.:backup|11.4 Key Backup]] | Backup before rotation |
| **Next Step** | [[.:vernichtung|11.5 Key Destruction]] | Delete old keys |
| **Related** | [[en:int:pqcrypt:szenarien:verwaltung:rekey|4.2 Rekey]] | Certificate with new key |
----
<< [[.:speicherung|← 11.2 Key Storage]] | [[.:start|↑ Key Overview]] | [[.:backup|11.4 Key Backup →]] >>
{{tag>scenario key rotation lifecycle compliance}}
----
//Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional//