Inhaltsverzeichnis
X509StoreExtensions
Namespace: WvdS.System.Security.Cryptography.X509Certificates
Extensions for X509Store with post-quantum key persistence. Enables saving and restoring PQ keys in the Windows Certificate Store.
Overview
The Windows Certificate Store does not natively support post-quantum keys. These extensions store PQ keys in a separate, encrypted file storage:
%LOCALAPPDATA%\WvdS.Crypto\PqKeys\{thumbprint}.pqkey
The keys are automatically encrypted with DPAPI (Windows) or AES-256 (cross-platform).
Methods
| Method | Description |
|---|---|
Add(certificate, mode) | Adds certificate and persists PQ keys |
AddRange(collection, mode) | Adds multiple certificates |
Remove(certificate, deletePqKeys) | Removes certificate and optionally PQ keys |
RemoveRange(collection, deletePqKeys) | Removes multiple certificates |
Find(findType, findValue, validOnly, restorePqKeys) | Searches certificates and restores PQ keys |
GetCertificatesWithPqKeys() | All certificates with restored PQ keys |
Static Methods
| Method | Description |
|---|---|
PersistPqKeys(certificate) | Manually persists PQ keys |
RestorePqKeys(certificate) | Manually restores PQ keys |
DeletePqKeys(certificate) | Deletes persisted PQ keys |
HasPersistedPqKeys(certificate) | Checks if PQ keys exist |
GetPersistedPqKeyThumbprints() | Lists all thumbprints |
Adding a Certificate
using var store = new X509Store(StoreName.My, StoreLocation.CurrentUser); store.Open(OpenFlags.ReadWrite); // Add certificate with PQ keys var hybridCert = CreateHybridCertificate(); store.Add(hybridCert, CryptoMode.Hybrid); // PQ keys are automatically persisted Console.WriteLine($"PQ keys saved: {X509StoreExtensions.HasPersistedPqKeys(hybridCert)}");
Finding Certificate with PQ Keys
using var store = new X509Store(StoreName.My, StoreLocation.CurrentUser); store.Open(OpenFlags.ReadOnly); // Search and restore PQ keys var certs = store.Find( X509FindType.FindBySubjectName, "MyCertificate", validOnly: true, restorePqKeys: true); // Automatically load PQ keys foreach (var cert in certs) { Console.WriteLine($"Found: {cert.Subject}"); Console.WriteLine($"Mode: {cert.GetCryptoMode()}"); // PQ keys are now available if (PqKeyStore.TryGetPublicKey(cert, out var pqKey)) { Console.WriteLine($"PQ key: {pqKey.Length} bytes"); } }
All Certificates with PQ Keys
using var store = new X509Store(StoreName.My, StoreLocation.CurrentUser); store.Open(OpenFlags.ReadOnly); var allCerts = store.GetCertificatesWithPqKeys(); foreach (var cert in allCerts) { var hasPq = X509StoreExtensions.HasPersistedPqKeys(cert); Console.WriteLine($"{cert.Subject}: PQ={hasPq}"); }
Removing a Certificate
using var store = new X509Store(StoreName.My, StoreLocation.CurrentUser); store.Open(OpenFlags.ReadWrite); var certToRemove = FindCertificate(store); // With PQ key cleanup (recommended) store.Remove(certToRemove, deletePqKeys: true); // Without PQ key cleanup (keys remain) store.Remove(certToRemove, deletePqKeys: false);
PqKeyStoreManager
Additional class for store management:
// Clean up orphaned keys (keys without associated certificate) int deleted = PqKeyStoreManager.CleanupOrphanedKeys( StoreName.My, StoreLocation.CurrentUser); Console.WriteLine($"{deleted} orphaned keys deleted"); // Backup all PQ keys PqKeyStoreManager.BackupAllPqKeys( "pq-keys-backup.enc", "BackupPassword123!"); // Restore from backup int restored = PqKeyStoreManager.RestoreFromBackup( "pq-keys-backup.enc", "BackupPassword123!"); Console.WriteLine($"{restored} keys restored");
Key Encryption
Windows (DPAPI)
DataProtectionScope.CurrentUser - Only the current user can decrypt keys - Keys are bound to user profile
Cross-Platform (AES-256)
Key = SHA256(MachineName + UserName) IV = randomly generated - Keys are bound to machine + user - Less secure than DPAPI
Secure Deletion
PQ keys are securely deleted:
// Internally executed: // 1. Overwrite file with random data var random = RandomNumberGenerator.GetBytes(fileLength); File.WriteAllBytes(keyPath, random); // 2. Delete file File.Delete(keyPath);
Example: Complete Workflow
// 1. Create hybrid certificate CryptoConfig.EnablePostQuantum(); var cert = CreateHybridCertificate("CN=Hybrid Test"); // 2. Add to store using (var store = new X509Store(StoreName.My, StoreLocation.CurrentUser)) { store.Open(OpenFlags.ReadWrite); store.Add(cert, CryptoMode.Hybrid); } // 3. Restart application... // 4. Load again later using (var store = new X509Store(StoreName.My, StoreLocation.CurrentUser)) { store.Open(OpenFlags.ReadOnly); var found = store.Find( X509FindType.FindBySubjectName, "Hybrid Test", true, restorePqKeys: true); var loadedCert = found[0]; // PQ keys are restored! var pqPublicKey = PqKeyStore.GetPublicKey(loadedCert); Console.WriteLine($"PQ key loaded: {pqPublicKey.Length} bytes"); }
Storage Location
| Operating System | Path |
|---|---|
| Windows | %LOCALAPPDATA%\WvdS.Crypto\PqKeys\ |
| Linux | ~/.local/share/WvdS.Crypto/PqKeys/ |
| macOS | ~/Library/Application Support/WvdS.Crypto/PqKeys/ |
Security Notes
- PQ keys are only accessible to the current user
- Create backup before system migration
- Run
CleanupOrphanedKeys()regularly - Cross-platform encryption is less secure than DPAPI
See Also
Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional
Zuletzt geändert: on 2026/01/30 at 12:18 AM