Scenario 11.1: Generazione chiavi
Categoria: Gestione chiavi
Complessità: Media
Prerequisiti: OpenSSL 3.6+, fonte di entropia sicura
Tempo stimato: 15-20 minuti
Descrizione
Questo scenario descrive la generazione sicura di chiavi crittografiche per algoritmi Post-Quantum. La generazione delle chiavi è il passo più critico - chiavi deboli compromettono tutte le operazioni basate su di esse.
Algoritmi supportati:
| Algoritmo | Tipo | Sicurezza | Dimensione chiave (Public) |
|---|---|---|---|
| ML-DSA-44 | Firma | 128-bit | 1.312 Bytes |
| ML-DSA-65 | Firma | 192-bit | 1.952 Bytes |
| ML-DSA-87 | Firma | 256-bit | 2.592 Bytes |
| ML-KEM-512 | KEM | 128-bit | 800 Bytes |
| ML-KEM-768 | KEM | 192-bit | 1.184 Bytes |
| ML-KEM-1024 | KEM | 256-bit | 1.568 Bytes |
Workflow
flowchart LR
ENTROPY[Fonte entropia] --> RNG[CSPRNG]
RNG --> KEYGEN[Generazione chiave]
PARAM[Scegliere parametri] --> KEYGEN
KEYGEN --> PUBKEY[Chiave pubblica]
KEYGEN --> PRIVKEY[Chiave privata]
PRIVKEY --> ENCRYPT[Salvare crittografata]
style ENTROPY fill:#fff3e0
style ENCRYPT fill:#e8f5e9
Esempio codice: Chiave firma ML-DSA
using WvdS.Security.Cryptography.X509Certificates.Extensions.PQ; using var ctx = PqCryptoContext.Initialize(); // Generare coppia chiavi ML-DSA-65 (consigliato) using var signatureKey = ctx.GenerateKeyPair(PqAlgorithm.MlDsa65); Console.WriteLine("Chiave ML-DSA-65 generata:"); Console.WriteLine($" Chiave pubblica: {signatureKey.PublicKey.GetRawData().Length} Bytes"); Console.WriteLine($" OID: {signatureKey.PublicKey.Oid.Value}"); // Salvare come PEM signatureKey.PublicKey.ToPemFile("signing.pub.pem"); signatureKey.ToEncryptedPemFile("signing.key.pem", "SecurePassword123!"); // Diversi livelli di sicurezza using var mlDsa44 = ctx.GenerateKeyPair(PqAlgorithm.MlDsa44); // 128-bit using var mlDsa65 = ctx.GenerateKeyPair(PqAlgorithm.MlDsa65); // 192-bit (Standard) using var mlDsa87 = ctx.GenerateKeyPair(PqAlgorithm.MlDsa87); // 256-bit (Alta sicurezza)
Esempio codice: Chiave crittografia ML-KEM
using var ctx = PqCryptoContext.Initialize(); // ML-KEM-768 per Key Encapsulation (consigliato) using var kemKey = ctx.GenerateKeyPair(PqAlgorithm.MlKem768); Console.WriteLine("Chiave ML-KEM-768 generata:"); Console.WriteLine($" Chiave pubblica: {kemKey.PublicKey.GetRawData().Length} Bytes"); Console.WriteLine($" Utilizzo: Key Encapsulation"); // Salvare kemKey.PublicKey.ToPemFile("encryption.pub.pem"); kemKey.ToEncryptedPemFile("encryption.key.pem", "EncryptionPassword!");
Esempio codice: Coppia chiavi ibride
public class HybridKeyPair { public AsymmetricAlgorithm ClassicalKey { get; set; } public PqKeyPair PqKey { get; set; } public static HybridKeyPair Generate( ClassicalAlgorithm classical, PqAlgorithm pq) { using var ctx = PqCryptoContext.Initialize(); // Chiave classica var classicalKey = classical switch { ClassicalAlgorithm.RsA4096 => RSA.Create(4096), ClassicalAlgorithm.EcdsaP384 => ECDsa.Create(ECCurve.NamedCurves.nistP384), ClassicalAlgorithm.EcdhP384 => ECDiffieHellman.Create(ECCurve.NamedCurves.nistP384), _ => throw new ArgumentException("Algoritmo sconosciuto") }; // Chiave PQ var pqKey = ctx.GenerateKeyPair(pq); return new HybridKeyPair { ClassicalKey = classicalKey, PqKey = pqKey }; } public void SaveToFiles(string baseName, string password) { // Chiave classica if (ClassicalKey is RSA rsa) { var rsaPem = rsa.ExportRSAPrivateKeyPem(); File.WriteAllText($"{baseName}-classical.key.pem", rsaPem); } else if (ClassicalKey is ECDsa ecdsa) { var ecPem = ecdsa.ExportECPrivateKeyPem(); File.WriteAllText($"{baseName}-classical.key.pem", ecPem); } // Chiave PQ PqKey.ToEncryptedPemFile($"{baseName}-pq.key.pem", password); PqKey.PublicKey.ToPemFile($"{baseName}-pq.pub.pem"); } } public enum ClassicalAlgorithm { RsA4096, EcdsaP384, EcdhP384 }
Generazione batch
public class KeyGenerationService { public Dictionary<string, PqKeyPair> GenerateBatch( int count, PqAlgorithm algorithm, string namePrefix) { using var ctx = PqCryptoContext.Initialize(); var keys = new Dictionary<string, PqKeyPair>(); for (int i = 0; i < count; i++) { var name = $"{namePrefix}-{i:D4}"; var keyPair = ctx.GenerateKeyPair(algorithm); keys[name] = keyPair; Console.WriteLine($"Generata: {name}"); } return keys; } public void SaveBatch( Dictionary<string, PqKeyPair> keys, string outputDir, string password) { Directory.CreateDirectory(outputDir); foreach (var (name, key) in keys) { key.PublicKey.ToPemFile(Path.Combine(outputDir, $"{name}.pub.pem")); key.ToEncryptedPemFile( Path.Combine(outputDir, $"{name}.key.pem"), password ); } } }
Entropia e numeri casuali
public class EntropySource { // Sistema CSPRNG (consigliato) public static byte[] GetSystemEntropy(int bytes) { return RandomNumberGenerator.GetBytes(bytes); } // Verificare Hardware RNG public static bool IsHardwareRngAvailable() { try { // Intel RDRAND return System.Runtime.Intrinsics.X86.Rdrand.IsSupported; } catch { return false; } } // Miscelare entropia aggiuntiva (opzionale) public static byte[] EnhancedEntropy(int bytes) { var systemEntropy = RandomNumberGenerator.GetBytes(bytes); // Miscelare altre fonti di entropia var timestamp = BitConverter.GetBytes(DateTime.UtcNow.Ticks); var processId = BitConverter.GetBytes(Environment.ProcessId); var gcMemory = BitConverter.GetBytes(GC.GetTotalMemory(false)); // Combinare con hash using var sha = SHA256.Create(); var combined = new byte[systemEntropy.Length + timestamp.Length + processId.Length + gcMemory.Length]; Buffer.BlockCopy(systemEntropy, 0, combined, 0, systemEntropy.Length); Buffer.BlockCopy(timestamp, 0, combined, systemEntropy.Length, timestamp.Length); Buffer.BlockCopy(processId, 0, combined, systemEntropy.Length + timestamp.Length, processId.Length); Buffer.BlockCopy(gcMemory, 0, combined, systemEntropy.Length + timestamp.Length + processId.Length, gcMemory.Length); var hashed = sha.ComputeHash(combined); // Entropia estesa per ulteriori bytes var result = new byte[bytes]; for (int i = 0; i < bytes; i += 32) { var blockSize = Math.Min(32, bytes - i); Buffer.BlockCopy(hashed, 0, result, i, blockSize); hashed = sha.ComputeHash(hashed); } return result; } }
Requisiti specifici per settore
| Settore | Sicurezza min. | Algoritmo consigliato | HSM obbligatorio? |
|---|---|---|---|
| IT Standard | 128-bit | ML-DSA-65 / ML-KEM-768 | No |
| Finanza | 192-bit | ML-DSA-65 / ML-KEM-768 | Sì |
| Sanità | 192-bit | ML-DSA-65 / ML-KEM-768 | Consigliato |
| Governo | 256-bit | ML-DSA-87 / ML-KEM-1024 | Sì |
| IoT | 128-bit | ML-DSA-44 / ML-KEM-512 | No |
Scenari correlati
| Relazione | Scenario | Descrizione |
|---|---|---|
| Passo successivo | 11.2 Archiviazione chiavi | Archiviazione sicura |
| Correlato | 11.3 Rotazione chiavi | Scambio regolare |
| Correlato | 2.1 CSR Server | Creare CSR |
« Panoramica chiavi | Scenari | 11.2 Archiviazione chiavi »
Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional
Zuletzt geändert: il 30/01/2026 alle 06:38