~~NOTOC~~ ====== Scenarij 12.1: PEM izvoz/uvoz ====== **Kategorija:** [[.:start|Uvoz/Izvoz]] \\ **Kompleksnost:** ⭐⭐ (Nizka) \\ **Predpogoji:** Certifikat ali ključ \\ **Predviden čas:** 10-15 minut ---- ===== Opis ===== Ta scenarij opisuje **izvoz in uvoz v PEM formatu** (Privacy-Enhanced Mail). PEM je najpogostejši format za certifikate in ključe na Linux/Unix sistemih in ga OpenSSL izvorno podpira. **Lastnosti PEM:** * **Kodiranje:** Base64 z glavo/nogo * **Glava:** ''-----BEGIN CERTIFICATE-----'' itd. * **Berljivost:** Besedilna datoteka, enostavna za pregled * **Veriženje:** Več objektov v eni datoteki je možno ---- ===== Tipi PEM ===== ^ Tip ^ Glava ^ Vsebina ^ | Certifikat | ''BEGIN CERTIFICATE'' | X.509 certifikat | | Zasebni ključ | ''BEGIN PRIVATE KEY'' | PKCS#8 nešifriran | | Šifriran ključ | ''BEGIN ENCRYPTED PRIVATE KEY'' | PKCS#8 šifriran | | RSA ključ | ''BEGIN RSA PRIVATE KEY'' | PKCS#1 (zastarelo) | | CSR | ''BEGIN CERTIFICATE REQUEST'' | PKCS#10 CSR | | CRL | ''BEGIN X509 CRL'' | Seznam preklicanih certifikatov | ---- ===== Primer kode: Izvoz certifikata kot PEM ===== using WvdS.Security.Cryptography.X509Certificates.Extensions.PQ; using System.Security.Cryptography.X509Certificates; using var ctx = PqCryptoContext.Initialize(); // Nalaganje certifikata var cert = new X509Certificate2("certificate.pfx", "password"); // Izvoz kot PEM ctx.ToPemFile(cert, "certificate.pem"); // Ali kot niz string pemString = ctx.ToPem(cert); Console.WriteLine(pemString); // Izpis: // -----BEGIN CERTIFICATE----- // MIIBkTCB+wIJAK... (Base64) // -----END CERTIFICATE----- ---- ===== Primer kode: Zasebni ključ kot PEM ===== using var ctx = PqCryptoContext.Initialize(); // Generiranje ključa using var keyPair = ctx.GenerateKeyPair(PqAlgorithm.MlDsa65); // Nešifriran PEM (SAMO za teste!) keyPair.ToPemFile("private-key.pem"); // Šifriran PEM (PRIPOROČENO) keyPair.ToEncryptedPemFile( path: "private-key-encrypted.pem", password: "StrongPassword123!", pbeAlgorithm: PbeAlgorithm.Aes256Cbc, iterations: 100000 ); // Javni ključ ločeno keyPair.PublicKey.ToPemFile("public-key.pem"); ---- ===== Primer kode: Uvoz PEM ===== using var ctx = PqCryptoContext.Initialize(); // Nalaganje certifikata iz PEM var cert = ctx.LoadCertificate("certificate.pem"); Console.WriteLine($"Subject: {cert.Subject}"); Console.WriteLine($"Veljavno do: {cert.NotAfter:d}"); // Nalaganje šifriranega zasebnega ključa var privateKey = ctx.LoadPrivateKey( path: "private-key-encrypted.pem", password: "StrongPassword123!" ); // Kombinacija certifikata z zasebnim ključem var certWithKey = ctx.LoadCertificateWithPrivateKey( certPath: "certificate.pem", keyPath: "private-key-encrypted.pem", keyPassword: "StrongPassword123!" ); Console.WriteLine($"Ima zasebni ključ: {certWithKey.HasPrivateKey}"); ---- ===== Primer kode: Certifikatna veriga kot PEM ===== public class PemChainExporter { public void ExportChainAsPem( X509Certificate2 endEntity, X509Certificate2Collection chain, string outputPath) { using var ctx = PqCryptoContext.Initialize(); var sb = new StringBuilder(); // Končni certifikat najprej sb.AppendLine("# End-Entity Certificate"); sb.AppendLine(ctx.ToPem(endEntity)); // Nato vmesne CA 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($"Veriga izvožena: {outputPath}"); } public X509Certificate2Collection ImportChainFromPem(string pemPath) { using var ctx = PqCryptoContext.Initialize(); var pemContent = File.ReadAllText(pemPath); var collection = new X509Certificate2Collection(); // Ekstrakcija PEM blokov 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} certifikatov uvoženih"); return collection; } } ---- ===== Primer kode: CSR kot PEM ===== using var ctx = PqCryptoContext.Initialize(); // Ustvarjanje ključa in CSR using var keyPair = ctx.GenerateKeyPair(PqAlgorithm.MlDsa65); var csr = ctx.CreateCertificateRequest( keyPair, new DnBuilder() .AddCN("www.example.com") .AddO("Example GmbH") .Build() ); // Izvoz CSR kot PEM string csrPem = ctx.ToPem(csr); File.WriteAllText("request.csr", csrPem); // Izpis: // -----BEGIN CERTIFICATE REQUEST----- // MIIBkTCB+wIJAK... (Base64) // -----END CERTIFICATE REQUEST----- ---- ===== Primer kode: CRL kot PEM ===== using var ctx = PqCryptoContext.Initialize(); // Ustvarjanje CRL var crlBuilder = new CertificateRevocationListBuilder(); // ... dodajanje certifikatov ... var crlBytes = crlBuilder.Build(caCert, caKey, crlNumber, nextUpdate); // Izvoz CRL kot PEM var crlPem = new StringBuilder(); crlPem.AppendLine("-----BEGIN X509 CRL-----"); crlPem.AppendLine(Convert.ToBase64String(crlBytes, Base64FormattingOptions.InsertLineBreaks)); crlPem.AppendLine("-----END X509 CRL-----"); File.WriteAllText("revoked.crl.pem", crlPem.ToString()); // Nalaganje CRL iz PEM var crlContent = File.ReadAllText("revoked.crl.pem"); var base64 = Regex.Match(crlContent, @"-----BEGIN X509 CRL-----(.*?)-----END X509 CRL-----", RegexOptions.Singleline).Groups[1].Value.Trim(); var crlData = Convert.FromBase64String(base64); ---- ===== Pretvorba PEM z OpenSSL ===== # Pretvorba DER v PEM openssl x509 -in cert.der -inform DER -out cert.pem -outform PEM # Pretvorba PEM v DER openssl x509 -in cert.pem -inform PEM -out cert.der -outform DER # Pregled PEM certifikata openssl x509 -in cert.pem -text -noout # Šifriranje zasebnega ključa openssl pkcs8 -topk8 -in key.pem -out key-encrypted.pem -aes256 # Dešifriranje zasebnega ključa openssl pkcs8 -in key-encrypted.pem -out key.pem ---- ===== Panožna uporaba PEM ===== ^ Sistem ^ PEM format ^ Posebnost ^ | **Apache** | Ločene .crt in .key | SSLCertificateFile, SSLCertificateKeyFile | | **Nginx** | Veriga v eni .pem | ssl_certificate (fullchain) | | **HAProxy** | Cert + Key v eni datoteki | bind ... ssl crt combined.pem | | **OpenSSL** | Vsi formati | Standardno orodje | | **Kubernetes** | Base64 kodirano v Secrets | kubectl create secret tls | ---- ===== Povezani scenariji ===== ^ Povezava ^ Scenarij ^ Opis ^ | **Alternativa** | [[.:pfx_export|12.2 PFX izvoz]] | Windows format | | **Povezano** | [[.:pkcs7_chain|12.3 PKCS#7 veriga]] | Samo certifikati | | **Povezano** | [[sl:int:pqcrypt:szenarien:schluessel:speicherung|11.2 Hramba ključev]] | Varna hramba | ---- << [[.:start|← Pregled uvoza/izvoza]] | [[.:start|↑ Uvoz/Izvoz]] | [[.:pfx_export|12.2 PFX izvoz →]] >> {{tag>scenarij uvoz izvoz pem base64 openssl}} ---- //Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional//