~~NOTOC~~ ====== Scenario 12.1: PEM Export/Import ====== **Categoria:** [[.:start|Import/Export]] \\ **Complessita:** ⭐⭐ (Bassa) \\ **Prerequisiti:** Certificato o chiave \\ **Tempo stimato:** 10-15 minuti ---- ===== Descrizione ===== Questo scenario descrive l'**export e import in formato PEM** (Privacy-Enhanced Mail). PEM e il formato piu comune per certificati e chiavi su sistemi Linux/Unix ed e supportato nativamente da OpenSSL. **Caratteristiche PEM:** * **Encoding:** Base64 con Header/Footer * **Header:** ''-----BEGIN CERTIFICATE-----'' ecc. * **Leggibilita:** File di testo, facile da ispezionare * **Concatenazione:** Piu oggetti possibili in un file ---- ===== Tipi PEM ===== ^ Tipo ^ Header ^ Contenuto ^ | Certificato | ''BEGIN CERTIFICATE'' | Certificato X.509 | | Private Key | ''BEGIN PRIVATE KEY'' | PKCS#8 non crittografato | | Encrypted Key | ''BEGIN ENCRYPTED PRIVATE KEY'' | PKCS#8 crittografato | | RSA Key | ''BEGIN RSA PRIVATE KEY'' | PKCS#1 (legacy) | | CSR | ''BEGIN CERTIFICATE REQUEST'' | PKCS#10 CSR | | CRL | ''BEGIN X509 CRL'' | Certificate Revocation List | ---- ===== Esempio di codice: Esportare certificato come PEM ===== using WvdS.Security.Cryptography.X509Certificates.Extensions.PQ; using System.Security.Cryptography.X509Certificates; using var ctx = PqCryptoContext.Initialize(); // Caricare certificato var cert = new X509Certificate2("certificate.pfx", "password"); // Esportare come PEM ctx.ToPemFile(cert, "certificate.pem"); // Oppure come stringa string pemString = ctx.ToPem(cert); Console.WriteLine(pemString); // Output: // -----BEGIN CERTIFICATE----- // MIIBkTCB+wIJAK... (Base64) // -----END CERTIFICATE----- ---- ===== Esempio di codice: Private Key come PEM ===== using var ctx = PqCryptoContext.Initialize(); // Generare chiave using var keyPair = ctx.GenerateKeyPair(PqAlgorithm.MlDsa65); // PEM non crittografato (SOLO per test!) keyPair.ToPemFile("private-key.pem"); // PEM crittografato (RACCOMANDATO) keyPair.ToEncryptedPemFile( path: "private-key-encrypted.pem", password: "StrongPassword123!", pbeAlgorithm: PbeAlgorithm.Aes256Cbc, iterations: 100000 ); // Public Key separatamente keyPair.PublicKey.ToPemFile("public-key.pem"); ---- ===== Esempio di codice: Importare PEM ===== using var ctx = PqCryptoContext.Initialize(); // Caricare certificato da PEM var cert = ctx.LoadCertificate("certificate.pem"); Console.WriteLine($"Subject: {cert.Subject}"); Console.WriteLine($"Valido fino a: {cert.NotAfter:d}"); // Caricare Private Key crittografato var privateKey = ctx.LoadPrivateKey( path: "private-key-encrypted.pem", password: "StrongPassword123!" ); // Combinare certificato con Private Key var certWithKey = ctx.LoadCertificateWithPrivateKey( certPath: "certificate.pem", keyPath: "private-key-encrypted.pem", keyPassword: "StrongPassword123!" ); Console.WriteLine($"Ha Private Key: {certWithKey.HasPrivateKey}"); ---- ===== Esempio di codice: Catena di certificati come PEM ===== public class PemChainExporter { public void ExportChainAsPem( X509Certificate2 endEntity, X509Certificate2Collection chain, string outputPath) { using var ctx = PqCryptoContext.Initialize(); var sb = new StringBuilder(); // Certificato End-Entity prima sb.AppendLine("# End-Entity Certificate"); sb.AppendLine(ctx.ToPem(endEntity)); // Poi le CA intermedie foreach (var cert in chain.OrderBy(c => c.NotAfter)) { if (cert.Thumbprint != endEntity.Thumbprint) { sb.AppendLine($"# Intermediate: {cert.Subject}"); sb.AppendLine(ctx.ToPem(cert)); } } File.WriteAllText(outputPath, sb.ToString()); Console.WriteLine($"Chain esportata: {outputPath}"); } public X509Certificate2Collection ImportChainFromPem(string pemPath) { using var ctx = PqCryptoContext.Initialize(); var pemContent = File.ReadAllText(pemPath); var collection = new X509Certificate2Collection(); // Estrarre blocchi PEM var certPattern = @"-----BEGIN CERTIFICATE-----(.*?)-----END CERTIFICATE-----"; var matches = Regex.Matches(pemContent, certPattern, RegexOptions.Singleline); foreach (Match match in matches) { var base64 = match.Groups[1].Value.Trim(); var certBytes = Convert.FromBase64String(base64); collection.Add(new X509Certificate2(certBytes)); } Console.WriteLine($"{collection.Count} certificati importati"); return collection; } } ---- ===== Conversione PEM con OpenSSL ===== # Convertire DER a PEM openssl x509 -in cert.der -inform DER -out cert.pem -outform PEM # Convertire PEM a DER openssl x509 -in cert.pem -inform PEM -out cert.der -outform DER # Ispezionare certificato PEM openssl x509 -in cert.pem -text -noout # Crittografare Private Key openssl pkcs8 -topk8 -in key.pem -out key-encrypted.pem -aes256 # Decrittografare Private Key openssl pkcs8 -in key-encrypted.pem -out key.pem ---- ===== Utilizzo PEM specifico per settore ===== ^ Sistema ^ Formato PEM ^ Particolarita ^ | **Apache** | .crt e .key separati | SSLCertificateFile, SSLCertificateKeyFile | | **Nginx** | Chain in un .pem | ssl_certificate (fullchain) | | **HAProxy** | Cert + Key in un file | bind ... ssl crt combined.pem | | **OpenSSL** | Tutti i formati | Tool standard | | **Kubernetes** | Codificato Base64 in Secrets | kubectl create secret tls | ---- ===== Scenari correlati ===== ^ Relazione ^ Scenario ^ Descrizione ^ | **Alternativo** | [[.:pfx_export|12.2 PFX Export]] | Formato Windows | | **Correlato** | [[.:pkcs7_chain|12.3 PKCS#7 Chain]] | Solo certificati | | **Correlato** | [[it:int:pqcrypt:szenarien:schluessel:speicherung|11.2 Archiviazione chiavi]] | Conservazione sicura | ---- << [[.:start|← Panoramica Import/Export]] | [[.:start|↑ Import/Export]] | [[.:pfx_export|12.2 PFX Export →]] >> {{tag>scenario import export pem base64 openssl}} ---- //Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional//