Post-Quantum Cryptography Extensions für .NET - Drop-In Erweiterung der Microsoft System.Security.Cryptography Klassen.
Diese Bibliothek ermöglicht schrittweises Refactoring bestehender .NET-Anwendungen auf Post-Quantum Kryptographie (PQC) ohne umfangreiche Code-Änderungen.
Assembly: WvdS.System.Security.Cryptography.Extensions.dll
| Namespace | Beschreibung |
|---|---|
WvdS.System.Security.Cryptography | Basis-Klassen, Enums, Config |
WvdS.System.Security.Cryptography.X509Certificates | X.509 Extensions |
WvdS.System.Security.Cryptography.Interop | OpenSSL 3.6 P/Invoke |
CryptoMode Parameter aufClassic → delegiert an Microsoft .NETHybrid → nutzt .NET + OpenSSL InteropPostQuantum → nutzt nur OpenSSL InteropWichtig: Es gibt keine direkte Verbindung zwischen Extension Methods und libcrypto. Alle PQ-Operationen laufen über den Interop-Layer!
WvdS.System.Security.Cryptography
│
├── CryptoMode.cs
│ └── enum CryptoMode
│ ├── Classic // Nur RSA/ECDSA via .NET
│ ├── Hybrid // RSA/ECDSA + ML-DSA parallel
│ └── PostQuantum // Nur ML-DSA via OpenSSL
│
├── CryptoConfig.cs
│ └── static class CryptoConfig
│ ├── DefaultMode { get; set; }
│ └── OpenSslPath { get; set; }
│
├── Interop/
│ └── OpenSslInterop.cs
│ └── internal static class OpenSslInterop
│ ├── Initialize()
│ ├── GenerateMlDsaKeyPair()
│ ├── SignMlDsa()
│ ├── VerifyMlDsa()
│ └── CreatePqCertificate()
│
└── X509Certificates/
│
├── CertificateRequestExtensions.cs
│ └── static class CertificateRequestExtensions
│ ├── CreateSelfSigned(this, notBefore, notAfter, mode?)
│ └── Create(this, issuer, notBefore, notAfter, serial, mode?)
│
├── X509Certificate2Extensions.cs
│ └── static class X509Certificate2Extensions
│ ├── CopyWithPrivateKey(this, key, mode?)
│ ├── HasPqSignature(this)
│ ├── GetCryptoMode(this)
│ └── GetSignatureAlgorithmDescription(this)
│
└── X509ChainExtensions.cs
└── static class X509ChainExtensions
├── Build(this, cert, mode?)
├── IsFullyPqProtected(this)
└── GetChainCryptoModes(this)
| Mode | Beschreibung | Backend | Kompatibilität |
|---|---|---|---|
Classic | Nur klassische Algorithmen (RSA, ECDSA, SHA-2) | Microsoft .NET | Überall |
Hybrid | Klassisch + Post-Quantum parallel | .NET + OpenSSL 3.6 | Klassische Software kann Zertifikat lesen, PQ-Software nutzt zusätzlich ML-DSA |
PostQuantum | Nur Post-Quantum Algorithmen (ML-DSA, ML-KEM) | OpenSSL 3.6 | Nur PQ-fähige Software (z.B. ISAPI DLL) |
namespace WvdS.System.Security.Cryptography; /// <summary> /// Kryptographie-Modus für alle Operationen /// </summary> public enum CryptoMode { /// <summary> /// Nur klassische Algorithmen (RSA, ECDSA) /// → System.Security.Cryptography /// </summary> Classic = 0, /// <summary> /// Klassisch + Post-Quantum kombiniert /// → System.Security.Cryptography + OpenSSL 3.6 /// → Zertifikat funktioniert auch ohne PQ-Support /// </summary> Hybrid = 1, /// <summary> /// Nur Post-Quantum Algorithmen (ML-DSA, ML-KEM) /// → OpenSSL 3.6 /// → Benötigt PQ-fähige Software /// </summary> PostQuantum = 2 }
Wichtig: Instance Methods haben IMMER Vorrang vor Extension Methods!
Deshalb verwenden unsere Extensions einen zusätzlichen Parameter (CryptoMode? mode), damit die Signatur unterschiedlich ist.
| Aufruf | Parameter | Ziel |
|---|---|---|
request.CreateSelfSigned(a, b) | 2 | → Original .NET (Instance Method) |
request.CreateSelfSigned(a, b, null) | 3 | → WvdS Extension (CryptoConfig.DefaultMode) |
request.CreateSelfSigned(a, b, CryptoMode.Hybrid) | 3 | → WvdS Extension (OpenSSL) |
namespace WvdS.System.Security.Cryptography.X509Certificates; public static class CertificateRequestExtensions { /// <summary> /// Erstellt ein selbstsigniertes Zertifikat (Root CA) /// </summary> /// <param name="request">CertificateRequest</param> /// <param name="notBefore">Gültig ab</param> /// <param name="notAfter">Gültig bis</param> /// <param name="mode">CryptoMode (null = CryptoConfig.DefaultMode)</param> public static X509Certificate2 CreateSelfSigned( this CertificateRequest request, DateTimeOffset notBefore, DateTimeOffset notAfter, CryptoMode? mode) { var effectiveMode = mode ?? CryptoConfig.DefaultMode; return effectiveMode switch { CryptoMode.Classic => request.CreateSelfSigned(notBefore, notAfter), CryptoMode.Hybrid => CreateSelfSignedHybrid(request, notBefore, notAfter), CryptoMode.PostQuantum => CreateSelfSignedPostQuantum(request, notBefore, notAfter), _ => request.CreateSelfSigned(notBefore, notAfter) }; } /// <summary> /// Erstellt ein von einer CA signiertes Zertifikat /// </summary> public static X509Certificate2 Create( this CertificateRequest request, X509Certificate2 issuerCertificate, DateTimeOffset notBefore, DateTimeOffset notAfter, byte[] serialNumber, CryptoMode? mode) { var effectiveMode = mode ?? CryptoConfig.DefaultMode; return effectiveMode switch { CryptoMode.Classic => request.Create(issuerCertificate, notBefore, notAfter, serialNumber), CryptoMode.Hybrid => CreateHybrid(request, issuerCertificate, notBefore, notAfter, serialNumber), CryptoMode.PostQuantum => CreatePostQuantum(request, issuerCertificate, notBefore, notAfter, serialNumber), _ => request.Create(issuerCertificate, notBefore, notAfter, serialNumber) }; } }
namespace WvdS.System.Security.Cryptography.X509Certificates; public static class X509Certificate2Extensions { /// <summary> /// Kopiert Zertifikat mit Private Key /// </summary> public static X509Certificate2 CopyWithPrivateKey( this X509Certificate2 certificate, RSA privateKey, CryptoMode? mode) { var effectiveMode = mode ?? CryptoConfig.DefaultMode; return effectiveMode switch { CryptoMode.Classic => certificate.CopyWithPrivateKey(privateKey), CryptoMode.Hybrid => CopyWithPrivateKeyHybrid(certificate, privateKey), CryptoMode.PostQuantum => CopyWithPrivateKeyPostQuantum(certificate, privateKey), _ => certificate.CopyWithPrivateKey(privateKey) }; } /// <summary> /// Prüft ob das Zertifikat eine PQ-Signatur Extension hat /// </summary> public static bool HasPqSignature(this X509Certificate2 certificate) { return certificate.Extensions[PqSignatureOid] != null; } /// <summary> /// Ermittelt den CryptoMode des Zertifikats /// </summary> public static CryptoMode GetCryptoMode(this X509Certificate2 certificate) { if (IsPqOnlyAlgorithm(certificate.SignatureAlgorithm.Value)) return CryptoMode.PostQuantum; if (certificate.HasPqSignature()) return CryptoMode.Hybrid; return CryptoMode.Classic; } /// <summary> /// Gibt den Signatur-Algorithmus als lesbaren String zurück /// </summary> public static string GetSignatureAlgorithmDescription(this X509Certificate2 certificate) { var classic = certificate.SignatureAlgorithm.FriendlyName ?? "Unknown"; return certificate.GetCryptoMode() switch { CryptoMode.PostQuantum => "ML-DSA-65 (Post-Quantum)", CryptoMode.Hybrid => $"{classic} + ML-DSA-65 (Hybrid)", _ => classic }; } }
namespace WvdS.System.Security.Cryptography.X509Certificates; public static class X509ChainExtensions { /// <summary> /// Baut und validiert die Certificate Chain /// </summary> public static bool Build( this X509Chain chain, X509Certificate2 certificate, CryptoMode? mode) { var effectiveMode = mode ?? CryptoConfig.DefaultMode; return effectiveMode switch { CryptoMode.Classic => chain.Build(certificate), CryptoMode.Hybrid => BuildHybrid(chain, certificate), CryptoMode.PostQuantum => BuildPostQuantum(chain, certificate), _ => chain.Build(certificate) }; } /// <summary> /// Prüft ob die gesamte Chain PQ-geschützt ist /// </summary> public static bool IsFullyPqProtected(this X509Chain chain) { foreach (var element in chain.ChainElements) { if (element.Certificate.GetCryptoMode() == CryptoMode.Classic) return false; } return true; } /// <summary> /// Gibt die CryptoModes aller Zertifikate in der Chain zurück /// </summary> public static CryptoMode[] GetChainCryptoModes(this X509Chain chain) { var modes = new CryptoMode[chain.ChainElements.Count]; for (int i = 0; i < chain.ChainElements.Count; i++) { modes[i] = chain.ChainElements[i].Certificate.GetCryptoMode(); } return modes; } }
// Usings hinzufügen using WvdS.System.Security.Cryptography; using WvdS.System.Security.Cryptography.X509Certificates; // Bestehender Code - KEINE Änderung var cert = request.CreateSelfSigned(notBefore, notAfter); // → Original .NET
// Einzelne Aufrufe auf Extension umstellen var cert = request.CreateSelfSigned(notBefore, notAfter, CryptoMode.Hybrid); // → OpenSSL // Oder mit null für Config-Default var cert = request.CreateSelfSigned(notBefore, notAfter, null); // → CryptoConfig.DefaultMode
// Am Programmstart CryptoConfig.DefaultMode = CryptoMode.Hybrid; // Alle Aufrufe mit null nutzen jetzt Hybrid var cert = request.CreateSelfSigned(notBefore, notAfter, null); // → Hybrid
| Suchen | Ersetzen |
|---|---|
.CreateSelfSigned(notBefore, notAfter) | .CreateSelfSigned(notBefore, notAfter, null) |
.Create(issuerCertificate, notBefore, notAfter, serialNumber) | .Create(issuerCertificate, notBefore, notAfter, serialNumber, null) |
.CopyWithPrivateKey(privateKey) | .CopyWithPrivateKey(privateKey, null) |
chain.Build(certificate) | chain.Build(certificate, null) |
| OID | Beschreibung |
|---|---|
1.3.6.1.4.1.XXXXX.1.1 | WvdS PQ-Signatur Extension (Hybrid-Zertifikate) |
TODO: Eigene OID bei IANA registrieren!
| OID | Algorithmus | Security Level |
|---|---|---|
2.16.840.1.101.3.4.3.17 | ML-DSA-44 | NIST Level 2 |
2.16.840.1.101.3.4.3.18 | ML-DSA-65 | NIST Level 3 |
2.16.840.1.101.3.4.3.19 | ML-DSA-87 | NIST Level 5 |
| Plattform | Library |
|---|---|
| Windows x64 | libcrypto-3-x64.dll |
| Windows x86 | libcrypto-3.dll |
| Linux | libcrypto.so.3 |
| macOS | libcrypto.3.dylib |
WvdS.System.Security.Cryptography.Extensions/ │ ├── src/ │ └── WvdS.System.Security.Cryptography.Extensions/ │ ├── WvdS.System.Security.Cryptography.Extensions.csproj │ ├── CryptoMode.cs │ ├── CryptoConfig.cs │ ├── Interop/ │ │ └── OpenSslInterop.cs │ └── X509Certificates/ │ ├── CertificateRequestExtensions.cs │ ├── X509Certificate2Extensions.cs │ ├── X509ChainExtensions.cs │ └── Helpers/ │ ├── PqSignatureHelper.cs │ ├── PqKeyStore.cs │ └── TbsCertificateBuilder.cs │ ├── tests/ │ └── WvdS.System.Security.Cryptography.Extensions.Tests/ │ └── ... │ └── README.md
ALT+M):pqc:)// Basis-Syntax
{{:namespace:dateiname.svg}}
// Mit Breite
{{:namespace:dateiname.svg?800}}
// Mit Breite und Höhe
{{:namespace:dateiname.svg?800x600}}
// Mit Alternativtext
{{:namespace:dateiname.svg?800|Beschreibung des Bildes}}
// Ohne Link (nicht klickbar)
{{:namespace:dateiname.svg?nolink}}
// Direktlink zum Bild
{{:namespace:dateiname.svg?direct}}
// Kombiniert
{{:namespace:dateiname.svg?direct&800|Alternativtext}}
{{:bild.svg}} // Links
{{ :bild.svg}} // Rechts (Leerzeichen vor :)
{{ :bild.svg }} // Zentriert (Leerzeichen vor und nach)
| Version | Datum | Änderungen |
|---|---|---|
| 1.0.0 | TBD | Initial Release |
EMSR DATA d.o.o. - WvdS Post-Quantum Cryptography Extensions