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