~~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//