====== SymmetricEncryptionExtensions ======
**Namespace:** ''WvdS.System.Security.Cryptography.Encryption''
Statični razred za AES-GCM šifriranje s podporo za post-kvantne ključe. Podpira klasično, hibridno in čisto PQ-šifriranje.
===== Pregled =====
Ta razred ponuja tri pristope k šifriranju:
| Način | Klasičen | ML-KEM | Uporaba |
| Classic | RSA-OAEP / ECDH | - | Standardno .NET obnašanje |
| Hybrid | RSA-OAEP / ECDH | ✓ | Maksimalna varnost |
| PostQuantum | - | ✓ | Čisto post-kvantno |
===== AES-GCM s PQ-ključem =====
==== EncryptWithPqKey ====
Šifrira podatke z AES-GCM z uporabo ML-KEM skupne skrivnosti.
// Skupna skrivnost iz ML-KEM izmenjave ključev
byte[] sharedSecret = session.SharedSecret;
// Šifriranje
byte[] plaintext = Encoding.UTF8.GetBytes("Tajno sporočilo");
byte[] encrypted = SymmetricEncryptionExtensions.EncryptWithPqKey(
plaintext,
sharedSecret);
// Z dodatnimi overjenimi podatki (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); // Če uporabljeno pri šifriranju
string message = Encoding.UTF8.GetString(decrypted);
===== Hibridno šifriranje (RSA + ML-KEM) =====
Kombinira RSA-OAEP enkapsulacijo ključev z ML-KEM za kvantno-varno 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č prejemnika
mlKemPublicKey, // ML-KEM javni ključ prejemnika
CryptoMode.Hybrid);
// Serializacija za prenos
byte[] serialized = encrypted.ToBytes();
==== DecryptHybrid ====
// Deserializacija
HybridEncryptedData encrypted = HybridEncryptedData.FromBytes(serialized);
// Dešifriranje
byte[] plaintext = SymmetricEncryptionExtensions.DecryptHybrid(
encrypted,
rsaPrivateKey, // RSA zasebni ključ
mlKemPrivateKey); // ML-KEM zasebni ključ
===== ECDH + ML-KEM šifriranje =====
ECIES-podobno šifriranje z efemernim ECDH in 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č prejemnika
mlKemPublicKey, // ML-KEM javni ključ
CryptoMode.Hybrid);
// Efemerni ECDH javni ključ je v encrypted.EphemeralPublicKey
==== DecryptEcdhPq ====
byte[] plaintext = SymmetricEncryptionExtensions.DecryptEcdhPq(
encrypted,
recipientEcdhPrivateKey,
mlKemPrivateKey);
===== Osnovne AES-GCM operacije =====
Neposredno AES-256-GCM šifriranje brez enkapsulacije ključev.
==== EncryptAesGcm ====
byte[] key = RandomNumberGenerator.GetBytes(32); // 256-bitni ključ
byte[] plaintext = GetData();
// Standardni AES-GCM
byte[] encrypted = SymmetricEncryptionExtensions.EncryptAesGcm(
plaintext,
key);
// Z AAD
byte[] aad = Encoding.UTF8.GetBytes("message-context");
byte[] encryptedWithAad = SymmetricEncryptionExtensions.EncryptAesGcm(
plaintext,
key,
associatedData: aad);
**Izhodni format:**
┌─────────────────────────────────────────┐
│ [12 bajtov] Nonce (naključno generiran) │
│ [n bajtov] Šifrirano besedilo │
│ [16 bajtov] GCM overitvena značka │
└─────────────────────────────────────────┘
==== DecryptAesGcm ====
byte[] plaintext = SymmetricEncryptionExtensions.DecryptAesGcm(
encrypted,
key,
associatedData: aad); // Če uporabljeno
===== Tokovno šifriranje =====
Za velike datoteke s chunk-osnovno obdelavo.
==== 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 chunki (standard)
**Format chunkov:**
┌────────────────────────────────────────────┐
│ [12 bajtov] Osnovni Nonce │
├────────────────────────────────────────────┤
│ Chunk 0: │
│ [4 bajti] Dolžina chunka │
│ [n bajtov] Šifrirani podatki │
│ [16 bajtov] GCM značka │
├────────────────────────────────────────────┤
│ Chunk 1: (Nonce = Base + 1) │
│ [4 bajti] Dolžina chunka │
│ [n bajtov] Šifrirani podatki │
│ [16 bajtov] GCM značka │
├────────────────────────────────────────────┤
│ ... nadaljnji chunki ... │
├────────────────────────────────────────────┤
│ [4 bajti] Končna oznaka (0x00000000) │
└────────────────────────────────────────────┘
==== DecryptStream ====
using var inputStream = File.OpenRead("large-file.enc");
using var outputStream = File.Create("large-file.decrypted");
SymmetricEncryptionExtensions.DecryptStream(
inputStream,
outputStream,
key);
===== Izpeljava ključev =====
==== DeriveAesKey ====
Izpelje AES-256 ključ iz skupne skrivnosti.
byte[] sharedSecret = GetMlKemSharedSecret();
// Standardna izpeljava
byte[] aesKey = SymmetricEncryptionExtensions.DeriveAesKey(sharedSecret);
// S soljo in informacijami
byte[] salt = RandomNumberGenerator.GetBytes(32);
byte[] info = Encoding.UTF8.GetBytes("MyApp-Encryption-Key");
byte[] aesKeyCustom = SymmetricEncryptionExtensions.DeriveAesKey(
sharedSecret,
salt: salt,
info: info);
**Notranja implementacija:** HKDF-SHA256 z ''info="WvdS-PQ-AES-Key"''
==== DeriveMultipleKeys ====
Izpelje več ključev za različne namene.
byte[] sharedSecret = GetMlKemSharedSecret();
var (encryptionKey, macKey, iv) = SymmetricEncryptionExtensions.DeriveMultipleKeys(
sharedSecret,
salt: optionalSalt);
// encryptionKey: 32 bajtov (AES-256)
// macKey: 32 bajtov (HMAC)
// iv: 16 bajtov (inicializacijski vektor)
===== Razred HybridEncryptedData =====
Vsebnik za hibridno-šifrirane podatke s serializacijo.
==== Lastnosti ====
^ Lastnost ^ Tip ^ Opis ^
| ''Mode'' | CryptoMode | Uporabljen način šifriranja |
| ''ClassicEncapsulatedKey'' | byte[]? | RSA-šifriran vsebinski ključ |
| ''EphemeralPublicKey'' | byte[]? | Efemerni ECDH javni ključ |
| ''PqCiphertext'' | byte[]? | ML-KEM šifrirano besedilo |
| ''EncryptedContent'' | byte[] | AES-GCM šifrirani podatki |
==== Serializacija ====
HybridEncryptedData encrypted = EncryptData();
// V polje bajtov
byte[] serialized = encrypted.ToBytes();
// Iz polja bajtov
HybridEncryptedData restored = HybridEncryptedData.FromBytes(serialized);
===== Razred PqCrypto za udobje =====
Poenostavljen API za čisto PQ-šifriranje.
// Generiranje para ključev
var (publicKey, privateKey) = PqCrypto.GenerateKeyPair();
// Šifriranje
byte[] plaintext = Encoding.UTF8.GetBytes("Tajno sporočilo");
var (ciphertext, encryptedData) = PqCrypto.Encrypt(plaintext, publicKey);
// Dešifriranje
byte[] decrypted = PqCrypto.Decrypt(ciphertext, encryptedData, privateKey);
===== Pregled metod =====
==== SymmetricEncryptionExtensions ====
^ Metoda ^ Parametri ^ Vrnjeno ^
| ''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 ^ Vrnjeno ^
| ''GenerateKeyPair'' | - | (byte[] PublicKey, byte[] PrivateKey) |
| ''Encrypt'' | byte[] plaintext, byte[] recipientPublicKey | (byte[] Ciphertext, byte[] EncryptedData) |
| ''Decrypt'' | byte[] ciphertext, byte[] encryptedData, byte[] privateKey | byte[] |
===== Popoln primer =====
using WvdS.System.Security.Cryptography;
using WvdS.System.Security.Cryptography.Encryption;
// 1. Generiranje ključev (prejemnik)
using var rsa = RSA.Create(4096);
var (mlKemPublicKey, mlKemPrivateKey) = PqCrypto.GenerateKeyPair();
// 2. Prenos javnih ključev pošiljatelju
// (V praksi: Certifikat z vgrajenimi PQ-ključi)
// --- Pošiljatelj ---
// 3. Šifriranje sporočila
byte[] message = File.ReadAllBytes("document.pdf");
HybridEncryptedData encrypted = SymmetricEncryptionExtensions.EncryptHybrid(
message,
rsa, // Prejemnikov RSA javni ključ
mlKemPublicKey, // Prejemnikov ML-KEM javni ključ
CryptoMode.Hybrid);
// 4. Serializacija in pošiljanje
byte[] package = encrypted.ToBytes();
File.WriteAllBytes("document.encrypted", package);
// --- Prejemnik ---
// 5. Prejem in deserializacija
byte[] receivedPackage = File.ReadAllBytes("document.encrypted");
HybridEncryptedData receivedData = HybridEncryptedData.FromBytes(receivedPackage);
// 6. Dešifriranje
byte[] decrypted = SymmetricEncryptionExtensions.DecryptHybrid(
receivedData,
rsa, // Lasten RSA zasebni ključ
mlKemPrivateKey); // Lasten ML-KEM zasebni ključ
File.WriteAllBytes("document.decrypted.pdf", decrypted);
===== Varnostni nasveti =====
* AES-GCM nonce-i se NE SMEJO nikoli ponovno uporabiti
* V hibridnem načinu se ključ izpelje iz klasične IN PQ-skrivnosti
* ''DeriveAesKey'' brez soli je determinističen - samo za specifične primere uporabe
* Tokovno šifriranje uporablja inkrementalne nonce-e na chunk
**Kombiniranje ključev v hibridnem načinu:**
Combined Key = HKDF-SHA256(
ikm = classicSecret || pqSecret,
info = "WvdS-Hybrid-Key"
)
Tudi če napadalec kompromitira klasično skrivnost, ostane šifriranje zaščiteno s PQ-skrivnostjo (in obratno).
===== Glej tudi =====
* [[.:start|Encryption Namespace]]
* [[.:hybridencrypteddata|HybridEncryptedData]]
* [[.:pqcrypto|PqCrypto]]
* [[..:keyexchange:start|KeyExchange Namespace]]
* [[..:keyderivation:start|KeyDerivation Namespace]]
* [[sl:int:pqcrypt:konzepte:algorithmen:ml-kem|Algoritem ML-KEM]]
----
//Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional//