Scenario 11.5: Key Destruction
Category: Key Management
Complexity: ⭐⭐⭐⭐ (High)
Prerequisites: Key no longer needed, backups verified
Estimated Time: 20-30 Minutes
Description
This scenario describes the secure and irreversible destruction of cryptographic keys. Proper key destruction is the final step in the key lifecycle and critical for security.
Destruction Reasons:
- End of Life - Key lifecycle ended
- Compromise - Key possibly known
- Compliance - Retention periods expired
- Decommissioning - System being retired
- Algorithm Migration - Old keys after PQ transition
WARNING: Key destruction is irreversible! Ensure:
- All encrypted data is decrypted or no longer needed
- All signatures are validated or no longer relevant
- Backups have also been destroyed
Workflow
flowchart TD
INIT[Initiate destruction] --> CHECK{Checks}
CHECK --> DEP[Check dependencies]
DEP --> BAK[Locate backups]
BAK --> APPROVE{Approval?}
APPROVE -->|No| ABORT[Abort]
APPROVE -->|Yes| DESTROY[Overwrite key]
DESTROY --> BACKUP_DEL[Destroy backups]
BACKUP_DEL --> HSM_DEL[Delete HSM keys]
HSM_DEL --> LOG[Audit log]
LOG --> CERT[Certificate]
style DESTROY fill:#ffebee
style BACKUP_DEL fill:#ffebee
style HSM_DEL fill:#ffebee
Code Example: Secure Memory Deletion
using System.Security.Cryptography; using System.Runtime.InteropServices; public class SecureKeyDestruction { public void DestroyKeyInMemory(byte[] keyMaterial) { if (keyMaterial == null || keyMaterial.Length == 0) return; // 1. Overwrite with random data RandomNumberGenerator.Fill(keyMaterial); // 2. Overwrite with zeros Array.Clear(keyMaterial, 0, keyMaterial.Length); // 3. Overwrite again with random data RandomNumberGenerator.Fill(keyMaterial); // 4. Final overwrite with zeros CryptographicOperations.ZeroMemory(keyMaterial); Console.WriteLine($"Memory cleared: {keyMaterial.Length} bytes"); } public void DestroyKeyOnDisk(string keyFilePath) { if (!File.Exists(keyFilePath)) { Console.WriteLine($"File not found: {keyFilePath}"); return; } var fileInfo = new FileInfo(keyFilePath); var fileLength = fileInfo.Length; // Multiple overwrites (DoD 5220.22-M Standard) using (var fs = new FileStream(keyFilePath, FileMode.Open, FileAccess.Write)) { var buffer = new byte[4096]; // Pass 1: Overwrite with 0x00 OverwriteFile(fs, fileLength, 0x00); // Pass 2: Overwrite with 0xFF OverwriteFile(fs, fileLength, 0xFF); // Pass 3: Overwrite with random data OverwriteFileRandom(fs, fileLength); // Pass 4: Again with 0x00 OverwriteFile(fs, fileLength, 0x00); fs.Flush(); } // Rename file (obscure metadata) var randomName = Path.Combine( Path.GetDirectoryName(keyFilePath), Guid.NewGuid().ToString() ); File.Move(keyFilePath, randomName); // Delete file File.Delete(randomName); Console.WriteLine($"Key file securely deleted: {keyFilePath}"); } private void OverwriteFile(FileStream fs, long length, byte value) { fs.Seek(0, SeekOrigin.Begin); var buffer = new byte[4096]; Array.Fill(buffer, value); long remaining = length; while (remaining > 0) { int toWrite = (int)Math.Min(remaining, buffer.Length); fs.Write(buffer, 0, toWrite); remaining -= toWrite; } } private void OverwriteFileRandom(FileStream fs, long length) { fs.Seek(0, SeekOrigin.Begin); var buffer = new byte[4096]; long remaining = length; while (remaining > 0) { RandomNumberGenerator.Fill(buffer); int toWrite = (int)Math.Min(remaining, buffer.Length); fs.Write(buffer, 0, toWrite); remaining -= toWrite; } } }
Code Example: Complete Destruction with Protocol
public class KeyDestructionService { private readonly ILogger _logger; private readonly IAuditLog _auditLog; public async Task<DestructionCertificate> DestroyKeyAsync( string keyId, string reason, string authorizedBy, DestructionOptions options = null) { options ??= DestructionOptions.Default; var certificate = new DestructionCertificate { KeyId = keyId, DestructionId = Guid.NewGuid().ToString(), InitiatedAt = DateTime.UtcNow, Reason = reason, AuthorizedBy = authorizedBy }; try { // 1. Check dependencies await ValidateDestructionAsync(keyId, certificate); // 2. Destroy active key await DestroyPrimaryKeyAsync(keyId, certificate); // 3. Destroy all backups if (options.DestroyBackups) { await DestroyBackupsAsync(keyId, certificate); } // 4. Destroy HSM keys if (options.DestroyHsmKeys) { await DestroyHsmKeyAsync(keyId, certificate); } // 5. Create audit log certificate.CompletedAt = DateTime.UtcNow; certificate.Status = DestructionStatus.Completed; await _auditLog.LogAsync(new AuditEntry { Action = "KEY_DESTRUCTION", KeyId = keyId, Details = certificate, Timestamp = DateTime.UtcNow }); _logger.LogInformation( "Key {KeyId} successfully destroyed. Certificate: {DestructionId}", keyId, certificate.DestructionId); return certificate; } catch (Exception ex) { certificate.Status = DestructionStatus.Failed; certificate.Error = ex.Message; _logger.LogError(ex, "Key destruction failed: {KeyId}", keyId); throw; } } private async Task ValidateDestructionAsync(string keyId, DestructionCertificate cert) { // Check if active certificates still exist var activeCerts = await _certStore.FindByKeyIdAsync(keyId); if (activeCerts.Any(c => c.NotAfter > DateTime.UtcNow)) { throw new InvalidOperationException( $"Key {keyId} is still used by {activeCerts.Count} active certificates"); } cert.ValidationsPassed.Add("No active certificates"); // Check if retention period expired var metadata = await _keyStore.GetMetadataAsync(keyId); if (metadata.RetentionUntil > DateTime.UtcNow) { throw new InvalidOperationException( $"Retention period runs until {metadata.RetentionUntil:d}"); } cert.ValidationsPassed.Add("Retention period expired"); } } public class DestructionCertificate { public string DestructionId { get; set; } public string KeyId { get; set; } public string KeyFingerprint { get; set; } public DateTime InitiatedAt { get; set; } public DateTime? CompletedAt { get; set; } public string Reason { get; set; } public string AuthorizedBy { get; set; } public DestructionStatus Status { get; set; } public List<string> ValidationsPassed { get; set; } = new(); public bool PrimaryKeyDestroyed { get; set; } public int BackupsDestroyed { get; set; } public bool HsmKeyDestroyed { get; set; } public List<string> DestroyedLocations { get; set; } = new(); public string Error { get; set; } } public enum DestructionStatus { InProgress, Completed, Failed }
Destruction Standards
| Standard | Overwrites | Pattern | Application |
|---|---|---|---|
| DoD 5220.22-M | 3 | 0x00, 0xFF, Random | US Military |
| NIST SP 800-88 | 1-3 | Depends on media type | US Government |
| BSI-TL 03423 | 3 | Random, 0x00, 0xFF | German Authorities |
| Gutmann | 35 | Various patterns | Paranoid |
For SSDs and flash storage: Secure deletion requires special firmware commands (TRIM, Secure Erase). Software overwriting is not reliable!
Industry-Specific Destruction Requirements
| Industry | Requirement | Witnesses | Documentation |
|---|---|---|---|
| Financial Sector | PCI-DSS 3.6.6 | 2 persons | Destruction protocol |
| Healthcare | HIPAA | 1 witness | Audit log |
| Government | VS-NfD | Security Officer | Destruction certificate |
| KRITIS | BSI | 2 persons | Certificate + Protocol |
Related Scenarios
| Relationship | Scenario | Description |
|---|---|---|
| Prerequisite | 11.4 Key Backup | Identify all backups |
| Prerequisite | 11.3 Key Rotation | New keys before destruction |
| Related | 6.4 Revoke Certificate | Revoke before destruction |
| Related | 4.3 Archival | Alternative: Archive instead of destroy |
« ← 11.4 Key Backup | ↑ Key Overview | → All Scenarios »
Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional
Zuletzt geändert: on 2026/01/30 at 06:43 AM