~~NOTOC~~ ====== Scenarij 12.1: PEM izvoz/uvoz ====== **Kategorija:** [[.:start|Uvoz/Izvoz]] \\ **Složenost:** ⭐⭐ (Niska) \\ **Preduvjeti:** Certifikat ili ključ \\ **Procijenjeno vrijeme:** 10-15 minuta ---- ===== Opis ===== Ovaj scenarij opisuje **izvoz i uvoz u PEM formatu** (Privacy-Enhanced Mail). PEM je najčešći format za certifikate i ključeve na Linux/Unix sustavima i nativno ga podržava OpenSSL. **PEM svojstva:** * **Kodiranje:** Base64 sa zaglavljem/podnožjem * **Zaglavlje:** ''-----BEGIN CERTIFICATE-----'' itd. * **Čitljivost:** Tekstualna datoteka, lako za pregled * **Ulančavanje:** Više objekata moguće u jednoj datoteci ---- ===== PEM tipovi ===== ^ Tip ^ Zaglavlje ^ Sadržaj ^ | Certifikat | ''BEGIN CERTIFICATE'' | X.509 certifikat | | Privatni ključ | ''BEGIN PRIVATE KEY'' | PKCS#8 nešifriran | | Šifrirani ključ | ''BEGIN ENCRYPTED PRIVATE KEY'' | PKCS#8 šifriran | | RSA ključ | ''BEGIN RSA PRIVATE KEY'' | PKCS#1 (legacy) | | CSR | ''BEGIN CERTIFICATE REQUEST'' | PKCS#10 CSR | | CRL | ''BEGIN X509 CRL'' | Certificate Revocation List | ---- ===== Primjer koda: Izvoz certifikata kao PEM ===== using WvdS.Security.Cryptography.X509Certificates.Extensions.PQ; using System.Security.Cryptography.X509Certificates; using var ctx = PqCryptoContext.Initialize(); // Učitavanje certifikata var cert = new X509Certificate2("certificate.pfx", "password"); // Izvoz kao PEM ctx.ToPemFile(cert, "certificate.pem"); // Ili kao string string pemString = ctx.ToPem(cert); Console.WriteLine(pemString); // Izlaz: // -----BEGIN CERTIFICATE----- // MIIBkTCB+wIJAK... (Base64) // -----END CERTIFICATE----- ---- ===== Primjer koda: Privatni ključ kao PEM ===== using var ctx = PqCryptoContext.Initialize(); // Generiranje ključa using var keyPair = ctx.GenerateKeyPair(PqAlgorithm.MlDsa65); // Nešifrirani PEM (SAMO za testiranje!) keyPair.ToPemFile("private-key.pem"); // Šifrirani PEM (PREPORUČENO) keyPair.ToEncryptedPemFile( path: "private-key-encrypted.pem", password: "StrongPassword123!", pbeAlgorithm: PbeAlgorithm.Aes256Cbc, iterations: 100000 ); // Javni ključ zasebno keyPair.PublicKey.ToPemFile("public-key.pem"); ---- ===== Primjer koda: Uvoz PEM ===== using var ctx = PqCryptoContext.Initialize(); // Učitavanje certifikata iz PEM var cert = ctx.LoadCertificate("certificate.pem"); Console.WriteLine($"Subject: {cert.Subject}"); Console.WriteLine($"Vrijedi do: {cert.NotAfter:d}"); // Učitavanje šifriranog privatnog ključa var privateKey = ctx.LoadPrivateKey( path: "private-key-encrypted.pem", password: "StrongPassword123!" ); // Kombiniranje certifikata s privatnim ključem var certWithKey = ctx.LoadCertificateWithPrivateKey( certPath: "certificate.pem", keyPath: "private-key-encrypted.pem", keyPassword: "StrongPassword123!" ); Console.WriteLine($"Ima privatni ključ: {certWithKey.HasPrivateKey}"); ---- ===== Primjer koda: Lanac certifikata kao PEM ===== public class PemChainExporter { public void ExportChainAsPem( X509Certificate2 endEntity, X509Certificate2Collection chain, string outputPath) { using var ctx = PqCryptoContext.Initialize(); var sb = new StringBuilder(); // End-Entity certifikat prvi sb.AppendLine("# End-Entity Certificate"); sb.AppendLine(ctx.ToPem(endEntity)); // Zatim Intermediate 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($"Lanac izvezen: {outputPath}"); } public X509Certificate2Collection ImportChainFromPem(string pemPath) { using var ctx = PqCryptoContext.Initialize(); var pemContent = File.ReadAllText(pemPath); var collection = new X509Certificate2Collection(); // Ekstrahiranje PEM blokova 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} certifikata uvezeno"); return collection; } } ---- ===== Primjer koda: CSR kao PEM ===== using var ctx = PqCryptoContext.Initialize(); // Kreiranje ključa i CSR using var keyPair = ctx.GenerateKeyPair(PqAlgorithm.MlDsa65); var csr = ctx.CreateCertificateRequest( keyPair, new DnBuilder() .AddCN("www.example.com") .AddO("Example d.o.o.") .Build() ); // Izvoz CSR kao PEM string csrPem = ctx.ToPem(csr); File.WriteAllText("request.csr", csrPem); // Izlaz: // -----BEGIN CERTIFICATE REQUEST----- // MIIBkTCB+wIJAK... (Base64) // -----END CERTIFICATE REQUEST----- ---- ===== Primjer koda: CRL kao PEM ===== using var ctx = PqCryptoContext.Initialize(); // Kreiranje CRL var crlBuilder = new CertificateRevocationListBuilder(); // ... dodavanje certifikata ... var crlBytes = crlBuilder.Build(caCert, caKey, crlNumber, nextUpdate); // Izvoz CRL kao 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()); // Učitavanje 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); ---- ===== PEM konverzija s OpenSSL ===== # Konverzija DER u PEM openssl x509 -in cert.der -inform DER -out cert.pem -outform PEM # Konverzija PEM u DER openssl x509 -in cert.pem -inform PEM -out cert.der -outform DER # Pregled PEM certifikata openssl x509 -in cert.pem -text -noout # Šifriranje privatnog ključa openssl pkcs8 -topk8 -in key.pem -out key-encrypted.pem -aes256 # Dešifriranje privatnog ključa openssl pkcs8 -in key-encrypted.pem -out key.pem ---- ===== PEM uporaba specifična za industriju ===== ^ Sustav ^ PEM format ^ Posebnost ^ | **Apache** | Odvojeni .crt i .key | SSLCertificateFile, SSLCertificateKeyFile | | **Nginx** | Lanac u jednoj .pem | ssl_certificate (fullchain) | | **HAProxy** | Cert + Key u jednoj datoteci | bind ... ssl crt combined.pem | | **OpenSSL** | Svi formati | Standardni alat | | **Kubernetes** | Base64 kodirano u Secrets | kubectl create secret tls | ---- ===== Povezani scenariji ===== ^ Povezanost ^ Scenarij ^ Opis ^ | **Alternativa** | [[.:pfx_export|12.2 PFX izvoz]] | Windows format | | **Povezano** | [[.:pkcs7_chain|12.3 PKCS#7 lanac]] | Samo certifikati | | **Povezano** | [[hr:int:pqcrypt:szenarien:schluessel:speicherung|11.2 Pohrana ključeva]] | Sigurna pohrana | ---- << [[.: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//