Scenario 12.1: PEM Export/Import

Categoria: 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:


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 12.2 PFX Export Formato Windows
Correlato 12.3 PKCS#7 Chain Solo certificati
Correlato 11.2 Archiviazione chiavi Conservazione sicura

« ← Panoramica Import/Export | ↑ Import/Export | 12.2 PFX Export → »


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