Inhaltsverzeichnis
KeyDerivationExtensions
Namespace: WvdS.System.Security.Cryptography.KeyDerivation
Statička klasa za derivaciju ključeva (Key Derivation Functions) s Post-Quantum podrškom. Podržava HKDF, PBKDF2 i Argon2id.
Pregled
Podržani KDF algoritmi:
| KDF | Standard | Uporaba |
|---|---|---|
| HKDF | RFC 5869 | Sesijski ključevi iz dijeljenih tajnih ključeva |
| PBKDF2 | RFC 8018 | Ključevi temeljeni na lozinci |
| Argon2id | RFC 9106 | Memorijski zahtjevan KDF (lozinke) |
HKDF - Hash-bazirana derivacija ključeva
DeriveKey
Derivira ključeve iz dijeljenog tajnog ključa (HKDF-Extract-then-Expand).
// ML-KEM dijeljeni tajni ključ iz Key Exchange byte[] sharedSecret = session.SharedSecret; // Standardna derivacija (SHA-256) byte[] aesKey = KeyDerivationExtensions.DeriveKey( sharedSecret, outputLength: 32); // 256 bita // Sa salt i kontekst informacijom 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); // Opcionalno
HkdfExtract
Ekstrahira PRK (Pseudorandom Key) iz ulaznog ključnog materijala.
byte[] inputKeyMaterial = GetSharedSecret(); byte[] salt = RandomNumberGenerator.GetBytes(32); byte[] prk = KeyDerivationExtensions.HkdfExtract( inputKeyMaterial, salt: salt, hashAlgorithm: HashAlgorithmName.SHA256); // PRK ima istu duljinu kao hash izlaz (32 bajta za SHA-256)
HkdfExpand
Proširuje PRK na izlazni ključni materijal.
byte[] prk = GetPrk(); // Ključ za šifriranje 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 derivacija ključeva
Kombinira klasične (ECDH/DH) i PQ (ML-KEM) dijeljene tajne ključeve.
DeriveHybridKey
byte[] ecdhSecret = GetEcdhSharedSecret(); byte[] mlKemSecret = GetMlKemSharedSecret(); // Hibridni način: Oba tajni ključa se kombiniraju byte[] hybridKey = KeyDerivationExtensions.DeriveHybridKey( classicSecret: ecdhSecret, pqSecret: mlKemSecret, outputLength: 32, mode: CryptoMode.Hybrid); // Samo klasični byte[] classicKey = KeyDerivationExtensions.DeriveHybridKey( classicSecret: ecdhSecret, pqSecret: null, outputLength: 32, mode: CryptoMode.Classic); // Samo Post-Quantum byte[] pqKey = KeyDerivationExtensions.DeriveHybridKey( classicSecret: null, pqSecret: mlKemSecret, outputLength: 32, mode: CryptoMode.PostQuantum); // Prilagođeni info byte[] customKey = KeyDerivationExtensions.DeriveHybridKey( classicSecret: ecdhSecret, pqSecret: mlKemSecret, outputLength: 64, mode: CryptoMode.Hybrid, info: Encoding.UTF8.GetBytes("MyProtocol-v1"));
Kombinacija ključeva:
Hibridni način: IKM = classicSecret || pqSecret Key = HKDF-SHA256(IKM, info="WvdS-Hybrid-Key")
DeriveHybridKeyMaterial
Derivira više ključeva za različite namjene.
using HybridKeyMaterial keyMaterial = KeyDerivationExtensions.DeriveHybridKeyMaterial( classicSecret: ecdhSecret, pqSecret: mlKemSecret, mode: CryptoMode.Hybrid); // Uporaba byte[] encKey = keyMaterial.EncryptionKey; // 32 bajta byte[] macKey = keyMaterial.MacKey; // 32 bajta byte[] iv = keyMaterial.Iv; // 16 bajtova byte[] authKey = keyMaterial.AuthKey; // 32 bajta // IDisposable: Ključevi se sigurno brišu
PBKDF2 - Derivacija temeljena na lozinci
Pbkdf2
string password = "SecurePassword123!"; byte[] salt = RandomNumberGenerator.GetBytes(32); // Standardni PBKDF2 byte[] key = KeyDerivationExtensions.Pbkdf2( password, salt, iterations: 100000, outputLength: 32); // S PQ-entropijom (dodatna zaštita) byte[] pqEntropy = GetPqEntropy(); byte[] enhancedKey = KeyDerivationExtensions.Pbkdf2( password, salt, iterations: 100000, outputLength: 32, pqEntropy: pqEntropy, // Kombinira se sa salt hashAlgorithm: HashAlgorithmName.SHA512);
Pbkdf2WithPqSalt
PBKDF2 s PQ-pojačanim salt (javni ključ uključen je u izračun salt).
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 - Memorijski zahtjevan KDF
Argon2id putem OpenSSL 3.6 - otporan na GPU/ASIC napade.
Argon2id (Byte-Array)
byte[] password = Encoding.UTF8.GetBytes("SecurePassword"); byte[] salt = RandomNumberGenerator.GetBytes(16); // Najmanje 16 bajtova byte[] key = KeyDerivationExtensions.Argon2id( password, salt, outputLength: 32, // Duljina ključa iterations: 3, // Vremenski trošak (t) memoryKiB: 65536, // Memorija: 64 MB parallelism: 4); // Niti (p)
Argon2id (String)
string password = "UserPassword123"; byte[] salt = RandomNumberGenerator.GetBytes(16); byte[] key = KeyDerivationExtensions.Argon2id( password, salt, outputLength: 32, iterations: 3, memoryKiB: 65536, parallelism: 4);
Preporučeni parametri:
| Primjena | Iteracije (t) | Memorija (m) | Paralelizam (p) |
|---|---|---|---|
| Hashiranje lozinki | 3 | 64 MB | 4 |
| Visoka sigurnost | 4 | 256 MB | 4 |
| Niska memorija | 4 | 16 MB | 4 |
TLS derivacija ključeva
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 bajta var serverKey = keys.ServerWriteKey; // 32 bajta var clientIv = keys.ClientWriteIv; // 12 bajtova var serverIv = keys.ServerWriteIv; // 12 bajtova
DeriveTls13Keys
TLS 1.3 kompatibilan raspored ključeva.
byte[]? pskSecret = null; // Pre-Shared Key (opcionalno) 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;
Klase podataka
HybridKeyMaterial
Kontejner za derivirane ključeve sa sigurnim čišćenjem memorije.
| Svojstvo | Tip | Duljina | Opis |
|---|---|---|---|
EncryptionKey | byte[] | 32 | AES ključ |
MacKey | byte[] | 32 | HMAC ključ |
Iv | byte[] | 16 | Inicijalizacijski vektor |
AuthKey | byte[] | 32 | Autentifikacijski ključ |
using HybridKeyMaterial keys = DeriveKeys(); // Ključevi se sigurno brišu pri Dispose() // (CryptographicOperations.ZeroMemory)
TlsKeyMaterial
TLS 1.2 stil ključni materijal.
| Svojstvo | Tip | Opis |
|---|---|---|
MasterSecret | byte[] | 48 bajtova Master Secret |
ClientWriteKey | byte[] | Ključ za šifriranje na klijentskoj strani |
ServerWriteKey | byte[] | Ključ za šifriranje na serverskoj strani |
ClientWriteIv | byte[] | IV na klijentskoj strani |
ServerWriteIv | byte[] | IV na serverskoj strani |
ClientWriteMacKey | byte[] | Klijentov MAC ključ (prazan za GCM) |
ServerWriteMacKey | byte[] | Serverov MAC ključ (prazan za GCM) |
Tls13KeySchedule
TLS 1.3 raspored ključeva.
| Svojstvo | 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 metoda
HKDF
| Metoda | Parametri | Povratni tip |
|---|---|---|
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[] |
Hibridni
| Metoda | Parametri | Povratni tip |
|---|---|---|
DeriveHybridKey | byte[]? classicSecret, byte[]? pqSecret, int outputLength, CryptoMode, byte[]? info | byte[] |
DeriveHybridKeyMaterial | byte[]? classicSecret, byte[]? pqSecret, CryptoMode | HybridKeyMaterial |
PBKDF2
| Metoda | Parametri | Povratni tip |
|---|---|---|
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 | Povratni tip |
|---|---|---|
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 | Povratni tip |
|---|---|---|
DeriveTlsKeys | byte[] preMasterSecret, byte[] clientRandom, byte[] serverRandom, CryptoMode | TlsKeyMaterial |
DeriveTls13Keys | byte[]? psk, byte[]? ecdh, byte[]? pq, byte[] clientHello, byte[] serverHello, CryptoMode | Tls13KeySchedule |
Potpuni primjer
using WvdS.System.Security.Cryptography; using WvdS.System.Security.Cryptography.KeyDerivation; using WvdS.System.Security.Cryptography.KeyExchange; // 1. Izvršiti Key Exchange using var session = new KeyExchangeService(); await session.InitiateKeyExchangeAsync(recipientPublicKey, CryptoMode.Hybrid); // 2. Derivirati hibridni ključni materijal using HybridKeyMaterial keys = KeyDerivationExtensions.DeriveHybridKeyMaterial( classicSecret: session.ClassicSharedSecret, pqSecret: session.PqSharedSecret, mode: CryptoMode.Hybrid); // 3. Koristiti ključeve using var aes = Aes.Create(); aes.Key = keys.EncryptionKey; using var hmac = new HMACSHA256(keys.MacKey); // 4. Izvršiti šifriranje // ... // 5. Ključevi se automatski sigurno brišu
Sigurnosne napomene
- Sve
IDisposableklase implementirajuCryptographicOperations.ZeroMemory - Argon2id zahtijeva OpenSSL 3.6 (nije dostupan u .NET BCL)
- PBKDF2 s manje od 100.000 iteracija se ne preporučuje
- Salt mora uvijek biti nasumičan i dovoljno dugačak za PBKDF2/Argon2id (min. 16 bajtova)
U hibridnom načinu konačni ključ je kompromitiran samo ako su OBA tajna ključa (klasični I PQ) probijena. To pruža zaštitu i od klasičnih i od kvantnih napada.
Vidi također
Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional