SymmetricEncryptionExtensions

Namespace: WvdS.System.Security.Cryptography.Encryption

Statička klasa za AES-GCM šifriranje s podrškom za Post-Quantum ključeve. Podržava klasično, hibridno i čisto PQ šifriranje.

Pregled

Ova klasa nudi tri pristupa šifriranju:

Način Klasični ML-KEM Uporaba
Classic RSA-OAEP / ECDH - Standardno .NET ponašanje
Hybrid RSA-OAEP / ECDH Maksimalna sigurnost
PostQuantum - Čisto post-quantum

AES-GCM s PQ-ključem

EncryptWithPqKey

Šifrira podatke pomoću AES-GCM koristeći ML-KEM dijeljeni tajni ključ.

// Dijeljeni tajni ključ iz ML-KEM Key Exchange
byte[] sharedSecret = session.SharedSecret;
 
// Šifriranje
byte[] plaintext = Encoding.UTF8.GetBytes("Tajna poruka");
byte[] encrypted = SymmetricEncryptionExtensions.EncryptWithPqKey(
    plaintext,
    sharedSecret);
 
// S Additional Authenticated Data (AAD)
byte[] aad = Encoding.UTF8.GetBytes("Kontekst-Info");
byte[] encryptedWithAad = SymmetricEncryptionExtensions.EncryptWithPqKey(
    plaintext,
    sharedSecret,
    associatedData: aad);

DecryptWithPqKey

byte[] decrypted = SymmetricEncryptionExtensions.DecryptWithPqKey(
    encrypted,
    sharedSecret,
    associatedData: aad);  // Ako je korišteno pri šifriranju
 
string message = Encoding.UTF8.GetString(decrypted);

Hibridno šifriranje (RSA + ML-KEM)

Kombinira RSA-OAEP Key Encapsulation s ML-KEM za kvantno sigurno hibridno šifriranje.

EncryptHybrid

using var rsa = RSA.Create(4096);
var (mlKemPublicKey, mlKemPrivateKey) = PqCrypto.GenerateKeyPair();
 
byte[] plaintext = GetSecretData();
 
// Hibridno šifriranje (RSA + ML-KEM)
HybridEncryptedData encrypted = SymmetricEncryptionExtensions.EncryptHybrid(
    plaintext,
    rsa,  // RSA javni ključ primatelja
    mlKemPublicKey,  // ML-KEM javni ključ primatelja
    CryptoMode.Hybrid);
 
// Serijalizacija za prijenos
byte[] serialized = encrypted.ToBytes();

DecryptHybrid

// Deserijalizacija
HybridEncryptedData encrypted = HybridEncryptedData.FromBytes(serialized);
 
// Dešifriranje
byte[] plaintext = SymmetricEncryptionExtensions.DecryptHybrid(
    encrypted,
    rsaPrivateKey,  // RSA privatni ključ
    mlKemPrivateKey);  // ML-KEM privatni ključ

ECDH + ML-KEM šifriranje

ECIES-stil šifriranje s efemerni ECDH i ML-KEM.

EncryptEcdhPq

using var recipientEcdh = ECDiffieHellman.Create(ECCurve.NamedCurves.nistP384);
var (mlKemPublicKey, mlKemPrivateKey) = PqCrypto.GenerateKeyPair();
 
byte[] plaintext = GetSecretData();
 
// ECDH + ML-KEM hibridno šifriranje
HybridEncryptedData encrypted = SymmetricEncryptionExtensions.EncryptEcdhPq(
    plaintext,
    recipientEcdh,  // ECDH javni ključ primatelja
    mlKemPublicKey,  // ML-KEM javni ključ
    CryptoMode.Hybrid);
 
// Efemerni ECDH javni ključ sadržan je u encrypted.EphemeralPublicKey

DecryptEcdhPq

byte[] plaintext = SymmetricEncryptionExtensions.DecryptEcdhPq(
    encrypted,
    recipientEcdhPrivateKey,
    mlKemPrivateKey);

Osnovne AES-GCM operacije

Direktno AES-256-GCM šifriranje bez Key Encapsulation.

EncryptAesGcm

byte[] key = RandomNumberGenerator.GetBytes(32);  // 256-bitni ključ
byte[] plaintext = GetData();
 
// Standardni AES-GCM
byte[] encrypted = SymmetricEncryptionExtensions.EncryptAesGcm(
    plaintext,
    key);
 
// S AAD
byte[] aad = Encoding.UTF8.GetBytes("message-context");
byte[] encryptedWithAad = SymmetricEncryptionExtensions.EncryptAesGcm(
    plaintext,
    key,
    associatedData: aad);

Izlazni format:

┌─────────────────────────────────────────┐
│ [12 bajtova] Nonce (nasumično generirano) │
│ [n bajtova]  Šifrirani tekst             │
│ [16 bajtova] GCM Authentication Tag      │
└─────────────────────────────────────────┘

DecryptAesGcm

byte[] plaintext = SymmetricEncryptionExtensions.DecryptAesGcm(
    encrypted,
    key,
    associatedData: aad);  // Ako je korišteno

Stream-bazirano šifriranje

Za velike datoteke s obradom po dijelovima (chunk).

EncryptStream

byte[] key = RandomNumberGenerator.GetBytes(32);
 
using var inputStream = File.OpenRead("large-file.dat");
using var outputStream = File.Create("large-file.enc");
 
SymmetricEncryptionExtensions.EncryptStream(
    inputStream,
    outputStream,
    key,
    chunkSize: 64 * 1024);  // 64 KB dijelovi (standard)

Format dijelova:

┌────────────────────────────────────────────┐
│ [12 bajtova] Bazni Nonce                    │
├────────────────────────────────────────────┤
│ Dio 0:                                      │
│   [4 bajta] Duljina dijela                  │
│   [n bajtova] Šifrirani podaci              │
│   [16 bajtova] GCM Tag                      │
├────────────────────────────────────────────┤
│ Dio 1: (Nonce = Bazni + 1)                  │
│   [4 bajta] Duljina dijela                  │
│   [n bajtova] Šifrirani podaci              │
│   [16 bajtova] GCM Tag                      │
├────────────────────────────────────────────┤
│ ... daljnji dijelovi ...                    │
├────────────────────────────────────────────┤
│ [4 bajta] Završni marker (0x00000000)       │
└────────────────────────────────────────────┘

DecryptStream

using var inputStream = File.OpenRead("large-file.enc");
using var outputStream = File.Create("large-file.decrypted");
 
SymmetricEncryptionExtensions.DecryptStream(
    inputStream,
    outputStream,
    key);

Derivacija ključeva

DeriveAesKey

Derivira AES-256 ključ iz dijeljenog tajnog ključa.

byte[] sharedSecret = GetMlKemSharedSecret();
 
// Standardna derivacija
byte[] aesKey = SymmetricEncryptionExtensions.DeriveAesKey(sharedSecret);
 
// Sa salt i info
byte[] salt = RandomNumberGenerator.GetBytes(32);
byte[] info = Encoding.UTF8.GetBytes("MyApp-Encryption-Key");
 
byte[] aesKeyCustom = SymmetricEncryptionExtensions.DeriveAesKey(
    sharedSecret,
    salt: salt,
    info: info);

Interna implementacija: HKDF-SHA256 s info=„WvdS-PQ-AES-Key“

DeriveMultipleKeys

Derivira više ključeva za različite namjene.

byte[] sharedSecret = GetMlKemSharedSecret();
 
var (encryptionKey, macKey, iv) = SymmetricEncryptionExtensions.DeriveMultipleKeys(
    sharedSecret,
    salt: optionalSalt);
 
// encryptionKey: 32 bajta (AES-256)
// macKey: 32 bajta (HMAC)
// iv: 16 bajtova (inicijalizacijski vektor)

HybridEncryptedData klasa

Kontejner za hibridno šifrirane podatke sa serijalizacijom.

Svojstva

Svojstvo Tip Opis
Mode CryptoMode Korišteni način šifriranja
ClassicEncapsulatedKey byte[]? RSA-šifrirani ključ sadržaja
EphemeralPublicKey byte[]? Efemerni ECDH javni ključ
PqCiphertext byte[]? ML-KEM šifrirani tekst
EncryptedContent byte[] AES-GCM šifrirani podaci

Serijalizacija

HybridEncryptedData encrypted = EncryptData();
 
// U byte niz
byte[] serialized = encrypted.ToBytes();
 
// Iz byte niza
HybridEncryptedData restored = HybridEncryptedData.FromBytes(serialized);

PqCrypto pomoćna klasa

Pojednostavljen API za čisto PQ šifriranje.

// Generiranje para ključeva
var (publicKey, privateKey) = PqCrypto.GenerateKeyPair();
 
// Šifriranje
byte[] plaintext = Encoding.UTF8.GetBytes("Tajna poruka");
var (ciphertext, encryptedData) = PqCrypto.Encrypt(plaintext, publicKey);
 
// Dešifriranje
byte[] decrypted = PqCrypto.Decrypt(ciphertext, encryptedData, privateKey);

Pregled metoda

SymmetricEncryptionExtensions

Metoda Parametri Povratni tip
EncryptWithPqKey byte[] plaintext, byte[] sharedSecret, byte[]? aad byte[]
DecryptWithPqKey byte[] ciphertext, byte[] sharedSecret, byte[]? aad byte[]
EncryptHybrid byte[] plaintext, RSA pubKey, byte[] pqPubKey, CryptoMode? HybridEncryptedData
DecryptHybrid HybridEncryptedData, RSA privKey, byte[] pqPrivKey byte[]
EncryptEcdhPq byte[] plaintext, ECDiffieHellman pubKey, byte[] pqPubKey, CryptoMode? HybridEncryptedData
DecryptEcdhPq HybridEncryptedData, ECDiffieHellman privKey, byte[] pqPrivKey byte[]
EncryptAesGcm byte[] plaintext, byte[] key, byte[]? aad byte[]
DecryptAesGcm byte[] ciphertext, byte[] key, byte[]? aad byte[]
EncryptStream Stream input, Stream output, byte[] key, int chunkSize void
DecryptStream Stream input, Stream output, byte[] key void
DeriveAesKey byte[] sharedSecret, byte[]? salt, byte[]? info byte[]
DeriveMultipleKeys byte[] sharedSecret, byte[]? salt (byte[], byte[], byte[])

PqCrypto

Metoda Parametri Povratni tip
GenerateKeyPair - (byte[] PublicKey, byte[] PrivateKey)
Encrypt byte[] plaintext, byte[] recipientPublicKey (byte[] Ciphertext, byte[] EncryptedData)
Decrypt byte[] ciphertext, byte[] encryptedData, byte[] privateKey byte[]

Potpuni primjer

using WvdS.System.Security.Cryptography;
using WvdS.System.Security.Cryptography.Encryption;
 
// 1. Generiranje ključeva (primatelj)
using var rsa = RSA.Create(4096);
var (mlKemPublicKey, mlKemPrivateKey) = PqCrypto.GenerateKeyPair();
 
// 2. Slanje javnih ključeva pošiljatelju
// (U praksi: certifikat s ugrađenim PQ ključevima)
 
// --- Pošiljatelj ---
 
// 3. Šifriranje poruke
byte[] message = File.ReadAllBytes("document.pdf");
 
HybridEncryptedData encrypted = SymmetricEncryptionExtensions.EncryptHybrid(
    message,
    rsa,  // RSA javni ključ primatelja
    mlKemPublicKey,  // ML-KEM javni ključ primatelja
    CryptoMode.Hybrid);
 
// 4. Serijalizacija i slanje
byte[] package = encrypted.ToBytes();
File.WriteAllBytes("document.encrypted", package);
 
// --- Primatelj ---
 
// 5. Primanje i deserijalizacija
byte[] receivedPackage = File.ReadAllBytes("document.encrypted");
HybridEncryptedData receivedData = HybridEncryptedData.FromBytes(receivedPackage);
 
// 6. Dešifriranje
byte[] decrypted = SymmetricEncryptionExtensions.DecryptHybrid(
    receivedData,
    rsa,  // Vlastiti RSA privatni ključ
    mlKemPrivateKey);  // Vlastiti ML-KEM privatni ključ
 
File.WriteAllBytes("document.decrypted.pdf", decrypted);

Sigurnosne napomene

  • AES-GCM Nonce se NIKADA ne smije ponovno koristiti
  • U hibridnom načinu ključ se derivira iz klasičnog I PQ tajnog ključa
  • DeriveAesKey bez salt je deterministički - samo za specifične slučajeve uporabe
  • Stream šifriranje koristi inkrementalne nonce po dijelu
Kombiniranje ključeva u hibridnom načinu:
Combined Key = HKDF-SHA256(
    ikm = classicSecret || pqSecret,
    info = "WvdS-Hybrid-Key"
)

Čak i ako napadač kompromitira klasični tajni ključ, šifriranje ostaje zaštićeno PQ tajnim ključem (i obrnuto).

Vidi također


Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional

Zuletzt geändert: 30.01.2026. u 00:12