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);
Prednost: Čak i s identičnom lozinkom i baznim salt, za svakog primatelja (različiti PQ javni ključ) dobiva se drugačiji ključ.

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 IDisposable klase implementiraju CryptographicOperations.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)
Sigurnost hibridnog načina:

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

Zuletzt geändert: 30.01.2026. u 00:13