====== 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//