====== 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 =====
* [[.:start|Encryption prostor imena]]
* [[.:hybridencrypteddata|HybridEncryptedData]]
* [[.:pqcrypto|PqCrypto]]
* [[..:keyexchange:start|KeyExchange prostor imena]]
* [[..:keyderivation:start|KeyDerivation prostor imena]]
* [[hr:int:pqcrypt:konzepte:algorithmen:ml-kem|ML-KEM algoritam]]
----
//Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional//