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.
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) |
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
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)
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"));
Kombinira klasične (ECDH/DH) in PQ (ML-KEM) skupne skrivnosti.
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")
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
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);
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 preko OpenSSL 3.6 - odporen proti GPU/ASIC napadom.
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)
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 |
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
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;
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)
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) |
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 |
| 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[] |
| Metoda | Parametri | Vrnjeno |
|---|---|---|
DeriveHybridKey | byte[]? classicSecret, byte[]? pqSecret, int outputLength, CryptoMode, byte[]? info | byte[] |
DeriveHybridKeyMaterial | byte[]? classicSecret, byte[]? pqSecret, CryptoMode | HybridKeyMaterial |
| 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[] |
| 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[] |
| 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 |
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
IDisposable razredi implementirajo CryptographicOperations.ZeroMemoryV 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.
Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional