Inhaltsverzeichnis
KeyDerivationExtensions
Namespace: WvdS.System.Security.Cryptography.KeyDerivation
Statični razred za izpeljavo ključev (Key Derivation Functions) s podporo za post-kvantno kriptografijo. Podpira HKDF, PBKDF2 in Argon2id.
Pregled
Podprti KDF-algoritmi:
| KDF | Standard | Uporaba |
|---|---|---|
| HKDF | RFC 5869 | Sejni ključi iz skupnih skrivnosti |
| PBKDF2 | RFC 8018 | Ključi iz gesel |
| Argon2id | RFC 9106 | Memory-hard KDF (gesla) |
HKDF - Izpeljava ključev na osnovi zgostitve
DeriveKey
Izpelje ključe iz skupne skrivnosti (HKDF-Extract-then-Expand).
// ML-KEM skupna skrivnost iz izmenjave ključev byte[] sharedSecret = session.SharedSecret; // Standardna izpeljava (SHA-256) byte[] aesKey = KeyDerivationExtensions.DeriveKey( sharedSecret, outputLength: 32); // 256 bitov // S soljo in kontekstnimi informacijami byte[] salt = RandomNumberGenerator.GetBytes(32); byte[] info = Encoding.UTF8.GetBytes("MyApp-Session-Key"); byte[] sessionKey = KeyDerivationExtensions.DeriveKey( sharedSecret, outputLength: 32, salt: salt, info: info, hashAlgorithm: HashAlgorithmName.SHA384); // Opcijsko
HkdfExtract
Ekstrahira PRK (Pseudorandom Key) iz vhodnega materiala ključa.
byte[] inputKeyMaterial = GetSharedSecret(); byte[] salt = RandomNumberGenerator.GetBytes(32); byte[] prk = KeyDerivationExtensions.HkdfExtract( inputKeyMaterial, salt: salt, hashAlgorithm: HashAlgorithmName.SHA256); // PRK ima enako dolžino kot izhod zgoščevalne funkcije (32 bajtov pri SHA-256)
HkdfExpand
Razširi PRK v izhodni material ključa.
byte[] prk = GetPrk(); // Šifrirni ključ byte[] encKey = KeyDerivationExtensions.HkdfExpand( prk, outputLength: 32, info: Encoding.UTF8.GetBytes("encryption")); // MAC ključ byte[] macKey = KeyDerivationExtensions.HkdfExpand( prk, outputLength: 32, info: Encoding.UTF8.GetBytes("mac"));
Hibridna izpeljava ključev
Kombinira klasične (ECDH/DH) in PQ (ML-KEM) skupne skrivnosti.
DeriveHybridKey
byte[] ecdhSecret = GetEcdhSharedSecret(); byte[] mlKemSecret = GetMlKemSharedSecret(); // Hibridni način: Obe skrivnosti sta kombinirani byte[] hybridKey = KeyDerivationExtensions.DeriveHybridKey( classicSecret: ecdhSecret, pqSecret: mlKemSecret, outputLength: 32, mode: CryptoMode.Hybrid); // Samo klasično byte[] classicKey = KeyDerivationExtensions.DeriveHybridKey( classicSecret: ecdhSecret, pqSecret: null, outputLength: 32, mode: CryptoMode.Classic); // Samo post-kvantno byte[] pqKey = KeyDerivationExtensions.DeriveHybridKey( classicSecret: null, pqSecret: mlKemSecret, outputLength: 32, mode: CryptoMode.PostQuantum); // Lastne informacije byte[] customKey = KeyDerivationExtensions.DeriveHybridKey( classicSecret: ecdhSecret, pqSecret: mlKemSecret, outputLength: 64, mode: CryptoMode.Hybrid, info: Encoding.UTF8.GetBytes("MyProtocol-v1"));
Kombinacija ključev:
Hybrid Mode: IKM = classicSecret || pqSecret Key = HKDF-SHA256(IKM, info="WvdS-Hybrid-Key")
DeriveHybridKeyMaterial
Izpelje več ključev za različne namene.
using HybridKeyMaterial keyMaterial = KeyDerivationExtensions.DeriveHybridKeyMaterial( classicSecret: ecdhSecret, pqSecret: mlKemSecret, mode: CryptoMode.Hybrid); // Uporaba byte[] encKey = keyMaterial.EncryptionKey; // 32 bajtov byte[] macKey = keyMaterial.MacKey; // 32 bajtov byte[] iv = keyMaterial.Iv; // 16 bajtov byte[] authKey = keyMaterial.AuthKey; // 32 bajtov // IDisposable: Ključi so varno izbrisani
PBKDF2 - Izpeljava ključev iz gesel
Pbkdf2
string password = "SecurePassword123!"; byte[] salt = RandomNumberGenerator.GetBytes(32); // Standardni PBKDF2 byte[] key = KeyDerivationExtensions.Pbkdf2( password, salt, iterations: 100000, outputLength: 32); // S PQ-entropijo (dodatna zaščita) byte[] pqEntropy = GetPqEntropy(); byte[] enhancedKey = KeyDerivationExtensions.Pbkdf2( password, salt, iterations: 100000, outputLength: 32, pqEntropy: pqEntropy, // Kombinirana s soljo hashAlgorithm: HashAlgorithmName.SHA512);
Pbkdf2WithPqSalt
PBKDF2 s PQ-okrepljeno soljo (javni ključ je vključen v izračun soli).
string password = "UserPassword"; byte[] baseSalt = RandomNumberGenerator.GetBytes(16); byte[] mlKemPublicKey = GetRecipientPublicKey(); // Salt = SHA256(baseSalt || pqPublicKey) byte[] key = KeyDerivationExtensions.Pbkdf2WithPqSalt( password, baseSalt, mlKemPublicKey, iterations: 100000, outputLength: 32);
Argon2id - Memory-Hard KDF
Argon2id preko OpenSSL 3.6 - odporen proti GPU/ASIC napadom.
Argon2id (polje bajtov)
byte[] password = Encoding.UTF8.GetBytes("SecurePassword"); byte[] salt = RandomNumberGenerator.GetBytes(16); // Najmanj 16 bajtov byte[] key = KeyDerivationExtensions.Argon2id( password, salt, outputLength: 32, // Dolžina ključa iterations: 3, // Časovni stroški (t) memoryKiB: 65536, // Pomnilnik: 64 MB parallelism: 4); // Niti (p)
Argon2id (niz)
string password = "UserPassword123"; byte[] salt = RandomNumberGenerator.GetBytes(16); byte[] key = KeyDerivationExtensions.Argon2id( password, salt, outputLength: 32, iterations: 3, memoryKiB: 65536, parallelism: 4);
Priporočeni parametri:
| Aplikacija | Iteracije (t) | Pomnilnik (m) | Paralelizem (p) |
|---|---|---|---|
| Zgoščevanje gesel | 3 | 64 MB | 4 |
| Visoka varnost | 4 | 256 MB | 4 |
| Nizek pomnilnik | 4 | 16 MB | 4 |
TLS izpeljava ključev
DeriveTlsKeys (TLS 1.2 stil)
byte[] preMasterSecret = GetPreMasterSecret(); byte[] clientRandom = GetClientRandom(); byte[] serverRandom = GetServerRandom(); using TlsKeyMaterial keys = KeyDerivationExtensions.DeriveTlsKeys( preMasterSecret, clientRandom, serverRandom, mode: CryptoMode.Hybrid); // Uporaba var clientKey = keys.ClientWriteKey; // 32 bajtov var serverKey = keys.ServerWriteKey; // 32 bajtov var clientIv = keys.ClientWriteIv; // 12 bajtov var serverIv = keys.ServerWriteIv; // 12 bajtov
DeriveTls13Keys
TLS 1.3 kompatibilen razpored ključev.
byte[]? pskSecret = null; // Pre-Shared Key (opcijsko) byte[] ecdhSecret = GetEcdhSecret(); byte[] pqSecret = GetMlKemSecret(); byte[] clientHello = GetClientHelloBytes(); byte[] serverHello = GetServerHelloBytes(); using Tls13KeySchedule schedule = KeyDerivationExtensions.DeriveTls13Keys( pskSecret, ecdhSecret, pqSecret, clientHello, serverHello, mode: CryptoMode.Hybrid); // Handshake Traffic Secrets var clientHsSecret = schedule.ClientHandshakeTrafficSecret; var serverHsSecret = schedule.ServerHandshakeTrafficSecret; // Application Traffic Secrets var clientAppSecret = schedule.ClientApplicationTrafficSecret; var serverAppSecret = schedule.ServerApplicationTrafficSecret; // Resumption Secret var resumptionSecret = schedule.ResumptionMasterSecret;
Podatkovni razredi
HybridKeyMaterial
Vsebnik za izpeljane ključe z varnim čiščenjem pomnilnika.
| Lastnost | Tip | Dolžina | Opis |
|---|---|---|---|
EncryptionKey | byte[] | 32 | AES-ključ |
MacKey | byte[] | 32 | HMAC-ključ |
Iv | byte[] | 16 | Inicializacijski vektor |
AuthKey | byte[] | 32 | Overitveni ključ |
using HybridKeyMaterial keys = DeriveKeys(); // Ključi so pri Dispose() varno izbrisani // (CryptographicOperations.ZeroMemory)
TlsKeyMaterial
TLS 1.2 stil materiala ključev.
| Lastnost | Tip | Opis |
|---|---|---|
MasterSecret | byte[] | 48 bajtov Master Secret |
ClientWriteKey | byte[] | Šifrirni ključ na strani odjemalca |
ServerWriteKey | byte[] | Šifrirni ključ na strani strežnika |
ClientWriteIv | byte[] | IV na strani odjemalca |
ServerWriteIv | byte[] | IV na strani strežnika |
ClientWriteMacKey | byte[] | MAC ključ odjemalca (prazen pri GCM) |
ServerWriteMacKey | byte[] | MAC ključ strežnika (prazen pri GCM) |
Tls13KeySchedule
TLS 1.3 razpored ključev.
| Lastnost | Tip | Opis |
|---|---|---|
ClientHandshakeTrafficSecret | byte[]? | Client Handshake Traffic Secret |
ServerHandshakeTrafficSecret | byte[]? | Server Handshake Traffic Secret |
ClientApplicationTrafficSecret | byte[]? | Client Application Traffic Secret |
ServerApplicationTrafficSecret | byte[]? | Server Application Traffic Secret |
ResumptionMasterSecret | byte[]? | Session Resumption Secret |
Pregled metod
HKDF
| Metoda | Parametri | Vrnjeno |
|---|---|---|
DeriveKey | byte[] sharedSecret, int outputLength, byte[]? salt, byte[]? info, HashAlgorithmName? | byte[] |
HkdfExtract | byte[] ikm, byte[]? salt, HashAlgorithmName? | byte[] |
HkdfExpand | byte[] prk, int outputLength, byte[]? info, HashAlgorithmName? | byte[] |
Hibridno
| Metoda | Parametri | Vrnjeno |
|---|---|---|
DeriveHybridKey | byte[]? classicSecret, byte[]? pqSecret, int outputLength, CryptoMode, byte[]? info | byte[] |
DeriveHybridKeyMaterial | byte[]? classicSecret, byte[]? pqSecret, CryptoMode | HybridKeyMaterial |
PBKDF2
| Metoda | Parametri | Vrnjeno |
|---|---|---|
Pbkdf2 | string password, byte[] salt, int iterations, int outputLength, byte[]? pqEntropy, HashAlgorithmName? | byte[] |
Pbkdf2WithPqSalt | string password, byte[] baseSalt, byte[] pqPublicKey, int iterations, int outputLength | byte[] |
Argon2id
| Metoda | Parametri | Vrnjeno |
|---|---|---|
Argon2id | byte[] password, byte[] salt, int outputLength, int iterations, int memoryKiB, int parallelism | byte[] |
Argon2id | string password, byte[] salt, int outputLength, int iterations, int memoryKiB, int parallelism | byte[] |
TLS
| Metoda | Parametri | Vrnjeno |
|---|---|---|
DeriveTlsKeys | byte[] preMasterSecret, byte[] clientRandom, byte[] serverRandom, CryptoMode | TlsKeyMaterial |
DeriveTls13Keys | byte[]? psk, byte[]? ecdh, byte[]? pq, byte[] clientHello, byte[] serverHello, CryptoMode | Tls13KeySchedule |
Popoln primer
using WvdS.System.Security.Cryptography; using WvdS.System.Security.Cryptography.KeyDerivation; using WvdS.System.Security.Cryptography.KeyExchange; // 1. Izvedba izmenjave ključev using var session = new KeyExchangeService(); await session.InitiateKeyExchangeAsync(recipientPublicKey, CryptoMode.Hybrid); // 2. Izpeljava hibridnega materiala ključev using HybridKeyMaterial keys = KeyDerivationExtensions.DeriveHybridKeyMaterial( classicSecret: session.ClassicSharedSecret, pqSecret: session.PqSharedSecret, mode: CryptoMode.Hybrid); // 3. Uporaba ključev using var aes = Aes.Create(); aes.Key = keys.EncryptionKey; using var hmac = new HMACSHA256(keys.MacKey); // 4. Izvedba šifriranja // ... // 5. Ključi so samodejno varno izbrisani
Varnostni nasveti
- Vsi
IDisposablerazredi implementirajoCryptographicOperations.ZeroMemory - Argon2id potrebuje OpenSSL 3.6 (ni na voljo v .NET BCL)
- PBKDF2 z manj kot 100.000 iteracijami ni priporočljiv
- Sol mora biti pri PBKDF2/Argon2id vedno naključna in dovolj dolga (min. 16 bajtov)
V hibridnem načinu je končni ključ kompromitiran le, če sta ZLOMLJENI OBE skrivnosti (klasična IN PQ). To zagotavlja zaščito tako pred klasičnimi kot pred kvantnimi napadi.
Glej tudi
Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional