~~NOTOC~~
====== Scenario 4.1: Rinnovo certificato (Renewal) ======
**Categoria:** [[.:start|Gestire certificati]] \\
**Complessità:** Media \\
**Prerequisiti:** Certificato esistente, stessa chiave \\
**Tempo stimato:** 10-15 minuti
----
===== Descrizione =====
Questo scenario descrive il **rinnovo di un certificato in scadenza** mantenendo la coppia di chiavi esistente. Il Renewal è utile quando la chiave non è stata compromessa e la forza della chiave è ancora sufficiente.
**Renewal vs. Rekey:**
^ Aspetto ^ Renewal ^ Rekey ^
| Coppia chiavi | Stessa | Nuova |
| CSR | Opzionalmente nuovo | Obbligatoriamente nuovo |
| Subject | Può essere modificato | Può essere modificato |
| Motivo | Scadenza | Compromissione, upgrade |
----
===== Workflow =====
flowchart LR
LOAD[Caricare vecchio cert] --> CHECK[Verificare scadenza]
CHECK --> CSR[CSR con stessa chiave]
CSR --> ISSUE[Nuovo certificato]
ISSUE --> DEPLOY[Deployment]
DEPLOY --> REVOKE[Revocare vecchio]
style ISSUE fill:#e8f5e9
----
===== Esempio codice (C#) =====
using WvdS.Security.Cryptography.X509Certificates.Extensions.PQ;
using var ctx = PqCryptoContext.Initialize();
// Caricare certificato e chiave esistenti
var oldCert = ctx.LoadCertificate("server.crt.pem");
var existingKey = ctx.LoadPrivateKey("server.key.pem", "KeyPassword!");
// Caricare CA
var caCert = ctx.LoadCertificate("intermediate-ca.crt.pem");
var caKey = ctx.LoadPrivateKey("intermediate-ca.key.pem", "CaPassword!");
// Verificare se il renewal è opportuno
var daysUntilExpiry = (oldCert.NotAfter - DateTime.UtcNow).Days;
if (daysUntilExpiry > 90)
{
Console.WriteLine($"Certificato ancora valido per {daysUntilExpiry} giorni.");
}
// Creare CSR con chiave esistente
var csr = ctx.CreateCertificateRequest(
existingKey,
oldCert.SubjectName, // Mantenere subject
ctx.GetExtensions(oldCert) // Mantenere estensioni
);
// Emettere nuovo certificato
var newCert = ctx.IssueCertificate(
csr,
issuerCert: caCert,
issuerKey: caKey,
serialNumber: ctx.GenerateSerialNumber(), // Nuovo serial!
validFrom: DateTime.UtcNow.AddDays(-1), // Sovrapposizione
validDays: 365,
extensions: new ExtBuilder()
.BasicConstraints(ca: false, critical: true)
.KeyUsage(KeyUsageFlags.DigitalSignature | KeyUsageFlags.KeyEncipherment)
.ExtendedKeyUsage(ExtKeyUsage.ServerAuth)
.SubjectKeyIdentifier(existingKey.PublicKey) // Stesso SKI!
.AuthorityKeyIdentifier(caCert)
.CrlDistributionPoint("http://crl.example.com/intermediate.crl")
.Build()
);
// Salvare
newCert.ToPemFile("server-renewed.crt.pem");
Console.WriteLine("Certificato rinnovato:");
Console.WriteLine($" Vecchio Serial: {oldCert.SerialNumber}");
Console.WriteLine($" Nuovo Serial: {newCert.SerialNumber}");
Console.WriteLine($" Nuova scadenza: {newCert.NotAfter:yyyy-MM-dd}");
----
===== Verifica automatica renewal =====
// Verificare tutti i certificati nello store
public IEnumerable GetExpiringCertificates(
X509Store store,
int warningDays = 30)
{
store.Open(OpenFlags.ReadOnly);
try
{
return store.Certificates
.Where(c => c.NotAfter <= DateTime.UtcNow.AddDays(warningDays))
.Where(c => c.NotAfter > DateTime.UtcNow) // Non ancora scaduto
.OrderBy(c => c.NotAfter)
.ToList();
}
finally
{
store.Close();
}
}
// Utilizzo
using var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
var expiring = GetExpiringCertificates(store, warningDays: 30);
foreach (var cert in expiring)
{
Console.WriteLine($"AVVISO: {cert.Subject} scade il {cert.NotAfter:d}");
}
----
===== Cicli di renewal specifici per settore =====
^ Settore ^ Ciclo tipico ^ Anticipo renewal ^ Particolarità ^
| **IT standard** | 1 anno | 30 giorni | Automazione raccomandata |
| **Energia/SCADA** | 3-5 anni | 90 giorni | Considerare finestre manutenzione |
| **Sanità** | 1-2 anni | 60 giorni | Audit trail richiesto |
| **Automotive** | 2-3 anni | 180 giorni | Pianificazione aggiornamento OTA |
----
===== Best practices =====
**Raccomandazioni per il renewal:**
* Pianificare tempo di sovrapposizione (vecchio cert valido 1-7 giorni dopo renewal)
* Implementare monitoraggio automatico
* Revocare vecchio certificato solo dopo deployment riuscito
* Subject Key Identifier rimane uguale (facilita il tracking)
**Quando NON rinnovare:**
* Chiave possibilmente compromessa → [[.:rekey|Rekey]]
* Upgrade algoritmo necessario (RSA → ML-DSA) → [[.:rekey|Rekey]]
* Lunghezza chiave insufficiente → [[.:rekey|Rekey]]
----
===== Scenari correlati =====
^ Relazione ^ Scenario ^ Descrizione ^
| **Alternativa** | [[.:rekey|4.2 Rekey]] | Nuova chiave |
| **Passo successivo** | [[it:int:pqcrypt:szenarien:widerruf:zertifikat_widerrufen|6.4 Revocare]] | Vecchio certificato |
| **Correlato** | [[.:backup|4.4 Backup]] | Salvare prima del renewal |
----
<< [[.:start|← Panoramica gestione]] | [[it:int:pqcrypt:szenarien:start|↑ Scenari]] | [[.:rekey|4.2 Rekey →]] >>
{{tag>scenario gestione renewal rinnovo certificato}}
----
//Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional//