~~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//