~~NOTOC~~
====== Scenario 11.3: Rotazione chiavi ======
**Categoria:** [[.:start|Gestione chiavi]] \\
**Complessità:** Alta \\
**Prerequisiti:** Chiavi esistenti, strategia di backup \\
**Tempo stimato:** 30-45 minuti
----
===== Descrizione =====
Questo scenario descrive la **rotazione regolare delle chiavi crittografiche**. La rotazione delle chiavi è una misura di sicurezza critica che limita il rischio di compromissione.
**Motivi di rotazione:**
* **Basata sul tempo** - Raggiunta durata massima della chiave
* **Basata sull'utilizzo** - Massime operazioni/volume dati
* **Incidente di sicurezza** - Sospetto di compromissione
* **Conformità** - Requisiti normativi
* **Upgrade algoritmo** - Migrazione ad algoritmi più forti
----
===== Workflow =====
flowchart TD
TRIGGER[Trigger rotazione] --> CHECK{Rotazione necessaria?}
CHECK -->|No| WAIT[Attendere]
CHECK -->|Sì| BACKUP[Backup chiave vecchia]
BACKUP --> GEN[Generare nuova chiave]
GEN --> MIGRATE[Migrare sistemi]
MIGRATE --> TEST[Test funzionale]
TEST --> OVERLAP{Sovrapposizione OK?}
OVERLAP -->|Sì| RETIRE[Disattivare chiave vecchia]
OVERLAP -->|No| ROLLBACK[Rollback]
RETIRE --> ARCHIVE[Archiviare/Eliminare]
style GEN fill:#e8f5e9
style BACKUP fill:#fff3e0
----
===== Esempio codice: Rotazione automatica =====
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);
// Verificare condizioni di rotazione
var needsRotation = ShouldRotate(metadata);
if (!needsRotation.Required)
{
return new RotationResult
{
KeyId = keyId,
Rotated = false,
Reason = "Nessuna rotazione necessaria"
};
}
return await PerformRotationAsync(keyId, metadata, needsRotation.Reason);
}
private RotationCheck ShouldRotate(KeyMetadata metadata)
{
// 1. Rotazione basata sul tempo
if (DateTime.UtcNow - metadata.CreatedAt > _maxKeyAge)
{
return new RotationCheck(true, "Età massima raggiunta");
}
// 2. Rotazione basata sull'utilizzo
if (metadata.OperationCount > _maxOperations)
{
return new RotationCheck(true, "Operazioni massime raggiunte");
}
// 3. Upgrade algoritmo (RSA → ML-DSA)
if (metadata.Algorithm.StartsWith("RSA") && !metadata.Algorithm.Contains("ML-DSA"))
{
return new RotationCheck(true, "Migrazione PQ necessaria");
}
return new RotationCheck(false, null);
}
private async Task PerformRotationAsync(
string keyId,
KeyMetadata oldMetadata,
string reason)
{
using var ctx = PqCryptoContext.Initialize();
// 1. Backup chiave vecchia
await _keyStore.BackupAsync(keyId);
// 2. Generare nuova chiave
var newKeyId = $"{keyId}-{DateTime.UtcNow:yyyyMMdd}";
using var newKey = ctx.GenerateKeyPair(PqAlgorithm.MlDsa65);
// 3. Salvare nuova chiave
await _keyStore.StoreAsync(newKeyId, newKey, new KeyMetadata
{
Algorithm = "ML-DSA-65",
CreatedAt = DateTime.UtcNow,
PreviousKeyId = keyId,
RotationReason = reason
});
// 4. Contrassegnare vecchia chiave come "in rotazione"
await _keyStore.SetStatusAsync(keyId, KeyStatus.Rotating);
return new RotationResult
{
KeyId = keyId,
NewKeyId = newKeyId,
Rotated = true,
Reason = reason
};
}
}
----
===== Esempio codice: Fase di sovrapposizione =====
public class OverlappingKeyManager
{
public async Task SignWithOverlap(
byte[] data,
string keyId,
IKeyStore keyStore)
{
using var ctx = PqCryptoContext.Initialize();
// Caricare chiave corrente
var currentKey = await keyStore.GetCurrentKeyAsync(keyId);
// Firmare con chiave corrente
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();
// Ottenere tutte le versioni valide della chiave
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)
{
// Chiave sbagliata, provare la prossima
continue;
}
}
return false;
}
}
----
===== Linee guida per la rotazione =====
^ Tipo chiave ^ Età max. ^ Operazioni max. ^ Sovrapposizione ^
| **Chiave Root-CA** | 10-20 anni | N/A | 1 anno |
| **Chiave Intermediate-CA** | 3-5 anni | N/A | 90 giorni |
| **Chiave TLS Server** | 1 anno | 10M handshake | 7 giorni |
| **Chiave Code Signing** | 2 anni | 100K firme | 30 giorni |
| **Chiave Encryption** | 1 anno | 100TB dati | 30 giorni |
----
===== Requisiti di rotazione specifici per settore =====
^ Settore ^ Ciclo rotazione ^ Requisito ^ Particolarità ^
| **Finanza** | 1 anno | PCI-DSS 3.6.4 | Obbligo Audit-Trail |
| **Sanità** | 2 anni | HIPAA | Key Escrow |
| **Energia/KRITIS** | 3 anni | BSI KRITIS-VO | Finestra manutenzione |
| **Enti pubblici** | 2 anni | BSI TR-03116 | Obbligo HSM |
----
===== Scenari correlati =====
^ Relazione ^ Scenario ^ Descrizione ^
| **Prerequisito** | [[.:speicherung|11.2 Archiviazione chiavi]] | Conservazione sicura |
| **Prerequisito** | [[.:backup|11.4 Backup chiavi]] | Backup prima della rotazione |
| **Passo successivo** | [[.:vernichtung|11.5 Distruzione chiavi]] | Eliminare chiavi vecchie |
| **Correlato** | [[it:int:pqcrypt:szenarien:verwaltung:rekey|4.2 Rekey]] | Certificato con nuova chiave |
----
<< [[.:speicherung|11.2 Archiviazione chiavi]] | [[.:start|Panoramica chiavi]] | [[.:backup|11.4 Backup chiavi]] >>
{{tag>scenario chiave rotazione lifecycle conformità}}
----
//Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional//