Szenario 12.1: PEM Export/Import

Kategorie: Import/Export
Komplexität: ⭐⭐ (Niedrig)
Voraussetzungen: Zertifikat oder Schlüssel
Geschätzte Zeit: 10-15 Minuten


Beschreibung

Dieses Szenario beschreibt den Export und Import im PEM-Format (Privacy-Enhanced Mail). PEM ist das gängigste Format für Zertifikate und Schlüssel auf Linux/Unix-Systemen und wird von OpenSSL nativ unterstützt.

PEM-Eigenschaften:

  • Encoding: Base64 mit Header/Footer
  • Header: —–BEGIN CERTIFICATE—– etc.
  • Lesbarkeit: Textdatei, leicht zu inspizieren
  • Verkettung: Mehrere Objekte in einer Datei möglich

PEM-Typen

Typ Header Inhalt
Zertifikat BEGIN CERTIFICATE X.509 Zertifikat
Private Key BEGIN PRIVATE KEY PKCS#8 unverschlüsselt
Encrypted Key BEGIN ENCRYPTED PRIVATE KEY PKCS#8 verschlüsselt
RSA Key BEGIN RSA PRIVATE KEY PKCS#1 (legacy)
CSR BEGIN CERTIFICATE REQUEST PKCS#10 CSR
CRL BEGIN X509 CRL Certificate Revocation List

Code-Beispiel: Zertifikat als PEM exportieren

using WvdS.Security.Cryptography.X509Certificates.Extensions.PQ;
using System.Security.Cryptography.X509Certificates;
 
using var ctx = PqCryptoContext.Initialize();
 
// Zertifikat laden
var cert = new X509Certificate2("certificate.pfx", "password");
 
// Als PEM exportieren
ctx.ToPemFile(cert, "certificate.pem");
 
// Oder als String
string pemString = ctx.ToPem(cert);
Console.WriteLine(pemString);
 
// Ausgabe:
// -----BEGIN CERTIFICATE-----
// MIIBkTCB+wIJAK... (Base64)
// -----END CERTIFICATE-----

Code-Beispiel: Private Key als PEM

using var ctx = PqCryptoContext.Initialize();
 
// Schlüssel generieren
using var keyPair = ctx.GenerateKeyPair(PqAlgorithm.MlDsa65);
 
// Unverschlüsseltes PEM (NUR für Tests!)
keyPair.ToPemFile("private-key.pem");
 
// Verschlüsseltes PEM (EMPFOHLEN)
keyPair.ToEncryptedPemFile(
    path: "private-key-encrypted.pem",
    password: "StrongPassword123!",
    pbeAlgorithm: PbeAlgorithm.Aes256Cbc,
    iterations: 100000
);
 
// Public Key separat
keyPair.PublicKey.ToPemFile("public-key.pem");

Code-Beispiel: PEM importieren

using var ctx = PqCryptoContext.Initialize();
 
// Zertifikat aus PEM laden
var cert = ctx.LoadCertificate("certificate.pem");
Console.WriteLine($"Subject: {cert.Subject}");
Console.WriteLine($"Gültig bis: {cert.NotAfter:d}");
 
// Verschlüsselten Private Key laden
var privateKey = ctx.LoadPrivateKey(
    path: "private-key-encrypted.pem",
    password: "StrongPassword123!"
);
 
// Zertifikat mit Private Key kombinieren
var certWithKey = ctx.LoadCertificateWithPrivateKey(
    certPath: "certificate.pem",
    keyPath: "private-key-encrypted.pem",
    keyPassword: "StrongPassword123!"
);
 
Console.WriteLine($"Hat Private Key: {certWithKey.HasPrivateKey}");

Code-Beispiel: Zertifikatskette als PEM

public class PemChainExporter
{
    public void ExportChainAsPem(
        X509Certificate2 endEntity,
        X509Certificate2Collection chain,
        string outputPath)
    {
        using var ctx = PqCryptoContext.Initialize();
        var sb = new StringBuilder();
 
        // End-Entity Zertifikat zuerst
        sb.AppendLine("# End-Entity Certificate");
        sb.AppendLine(ctx.ToPem(endEntity));
 
        // Dann Intermediate CAs
        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 exportiert: {outputPath}");
    }
 
    public X509Certificate2Collection ImportChainFromPem(string pemPath)
    {
        using var ctx = PqCryptoContext.Initialize();
        var pemContent = File.ReadAllText(pemPath);
        var collection = new X509Certificate2Collection();
 
        // PEM-Blöcke extrahieren
        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} Zertifikate importiert");
        return collection;
    }
}

Code-Beispiel: CSR als PEM

using var ctx = PqCryptoContext.Initialize();
 
// Schlüssel und CSR erstellen
using var keyPair = ctx.GenerateKeyPair(PqAlgorithm.MlDsa65);
 
var csr = ctx.CreateCertificateRequest(
    keyPair,
    new DnBuilder()
        .AddCN("www.example.com")
        .AddO("Example GmbH")
        .Build()
);
 
// CSR als PEM exportieren
string csrPem = ctx.ToPem(csr);
File.WriteAllText("request.csr", csrPem);
 
// Ausgabe:
// -----BEGIN CERTIFICATE REQUEST-----
// MIIBkTCB+wIJAK... (Base64)
// -----END CERTIFICATE REQUEST-----

Code-Beispiel: CRL als PEM

using var ctx = PqCryptoContext.Initialize();
 
// CRL erstellen
var crlBuilder = new CertificateRevocationListBuilder();
// ... Zertifikate hinzufügen ...
 
var crlBytes = crlBuilder.Build(caCert, caKey, crlNumber, nextUpdate);
 
// CRL als PEM exportieren
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());
 
// CRL aus PEM laden
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-Konvertierung mit OpenSSL

# DER zu PEM konvertieren
openssl x509 -in cert.der -inform DER -out cert.pem -outform PEM
 
# PEM zu DER konvertieren
openssl x509 -in cert.pem -inform PEM -out cert.der -outform DER
 
# PEM-Zertifikat inspizieren
openssl x509 -in cert.pem -text -noout
 
# Private Key verschlüsseln
openssl pkcs8 -topk8 -in key.pem -out key-encrypted.pem -aes256
 
# Private Key entschlüsseln
openssl pkcs8 -in key-encrypted.pem -out key.pem

Branchenspezifische PEM-Verwendung

System PEM-Format Besonderheit
Apache Separate .crt und .key SSLCertificateFile, SSLCertificateKeyFile
Nginx Chain in einer .pem ssl_certificate (fullchain)
HAProxy Cert + Key in einer Datei bind … ssl crt combined.pem
OpenSSL Alle Formate Standard-Tool
Kubernetes Base64-kodiert in Secrets kubectl create secret tls

Verwandte Szenarien

Beziehung Szenario Beschreibung
Alternative 12.2 PFX Export Windows-Format
Verwandt 12.3 PKCS#7 Chain Nur Zertifikate
Verwandt 11.2 Schlüsselspeicherung Sichere Aufbewahrung

« ← Import/Export-Übersicht | ↑ Import/Export | 12.2 PFX Export → »


Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional

Zuletzt geändert: den 29.01.2026 um 15:12