Criptografía Windows - Ejemplos C#

Ejemplos completos de criptografía C# para plataforma Windows incluyendo cálculo de hash, cifrado simétrico, cifrado asimétrico y firmas digitales

💻 Cálculo y Verificación de Hash csharp

🟢 simple ⭐⭐

Cálculo y verificación de hashes criptográficos usando MD5, SHA-1, SHA-256, SHA-512 para integridad y autenticación de datos

⏱️ 20 min 🏷️ csharp, cryptography, hashing, security, windows
Prerequisites: C# basics, Cryptography fundamentals
using System;
using System.Security.Cryptography;
using System.Text;
using System.IO;

class HashComputation
{
    // 1. Basic hash computation with different algorithms
    public static void BasicHashComputation()
    {
        Console.WriteLine("=== Basic Hash Computation ===");

        string message = "Hello, World! This is a test message for hashing.";
        byte[] messageBytes = Encoding.UTF8.GetBytes(message);

        Console.WriteLine($"Original message: {message}");
        Console.WriteLine($"Message length: {messageBytes.Length} bytes");
        Console.WriteLine();

        // MD5 hash
        using (MD5 md5 = MD5.Create())
        {
            byte[] md5Hash = md5.ComputeHash(messageBytes);
            string md5String = BitConverter.ToString(md5Hash).Replace("-", "").ToLowerInvariant();
            Console.WriteLine($"MD5:    {md5String} ({md5Hash.Length * 8} bits)");
        }

        // SHA-1 hash
        using (SHA1 sha1 = SHA1.Create())
        {
            byte[] sha1Hash = sha1.ComputeHash(messageBytes);
            string sha1String = BitConverter.ToString(sha1Hash).Replace("-", "").ToLowerInvariant();
            Console.WriteLine($"SHA-1:  {sha1String} ({sha1Hash.Length * 8} bits)");
        }

        // SHA-256 hash
        using (SHA256 sha256 = SHA256.Create())
        {
            byte[] sha256Hash = sha256.ComputeHash(messageBytes);
            string sha256String = BitConverter.ToString(sha256Hash).Replace("-", "").ToLowerInvariant();
            Console.WriteLine($"SHA-256:{sha256String} ({sha256Hash.Length * 8} bits)");
        }

        // SHA-384 hash
        using (SHA384 sha384 = SHA384.Create())
        {
            byte[] sha384Hash = sha384.ComputeHash(messageBytes);
            string sha384String = BitConverter.ToString(sha384Hash).Replace("-", "").ToLowerInvariant();
            Console.WriteLine($"SHA-384:{sha384String.Substring(0, 32)}... ({sha384Hash.Length * 8} bits)");
        }

        // SHA-512 hash
        using (SHA512 sha512 = SHA512.Create())
        {
            byte[] sha512Hash = sha512.ComputeHash(messageBytes);
            string sha512String = BitConverter.ToString(sha512Hash).Replace("-", "").ToLowerInvariant();
            Console.WriteLine($"SHA-512:{sha512String.Substring(0, 32)}... ({sha512Hash.Length * 8} bits)");
        }
    }

    // 2. File hashing for integrity verification
    public static void FileHashingExample()
    {
        Console.WriteLine("\n=== File Hashing Example ===");

        // Create a test file
        string testFilePath = "test_file.txt";
        string fileContent = "This is the content of our test file.\nIt contains multiple lines.\nWe will compute hash of this file.";

        File.WriteAllText(testFilePath, fileContent);
        Console.WriteLine($"Created test file: {testFilePath}");
        Console.WriteLine($"File content:\n{fileContent}");

        // Compute hashes of the file
        using (var fileStream = File.OpenRead(testFilePath))
        {
            using (MD5 md5 = MD5.Create())
            {
                byte[] md5Hash = md5.ComputeHash(fileStream);
                string md5String = BitConverter.ToString(md5Hash).Replace("-", "").ToLowerInvariant();
                Console.WriteLine($"\nFile MD5: {md5String}");
            }

            // Reset stream position for next hash
            fileStream.Position = 0;

            using (SHA256 sha256 = SHA256.Create())
            {
                byte[] sha256Hash = sha256.ComputeHash(fileStream);
                string sha256String = BitConverter.ToString(sha256Hash).Replace("-", "").ToLowerInvariant();
                Console.WriteLine($"File SHA-256: {sha256String}");
            }
        }

        // Simulate file modification and verification
        Console.WriteLine("\nSimulating file modification...");
        string modifiedContent = fileContent + "\nThis line was added to modify the file.";
        File.WriteAllText(testFilePath, modifiedContent);

        using (var fileStream = File.OpenRead(testFilePath))
        using (SHA256 sha256 = SHA256.Create())
        {
            byte[] newHash = sha256.ComputeHash(fileStream);
            string newHashString = BitConverter.ToString(newHash).Replace("-", "").ToLowerInvariant();
            Console.WriteLine($"Modified file SHA-256: {newHashString}");
            Console.WriteLine("Hash has changed (as expected)");
        }

        // Clean up
        File.Delete(testFilePath);
    }

    // 3. Hash-based Message Authentication Code (HMAC)
    public static void HMACExample()
    {
        Console.WriteLine("\n=== HMAC Example ===");

        string message = "This is a secret message that needs authentication.";
        string secretKey = "MySuperSecretKey123!@#";

        Console.WriteLine($"Message: {message}");
        Console.WriteLine($"Secret Key: {secretKey}");

        byte[] messageBytes = Encoding.UTF8.GetBytes(message);
        byte[] keyBytes = Encoding.UTF8.GetBytes(secretKey);

        // HMAC-MD5
        using (HMACMD5 hmacMd5 = new HMACMD5(keyBytes))
        {
            byte[] hmacHash = hmacMd5.ComputeHash(messageBytes);
            string hmacString = BitConverter.ToString(hmacHash).Replace("-", "").ToLowerInvariant();
            Console.WriteLine($"\nHMAC-MD5:   {hmacString}");
        }

        // HMAC-SHA1
        using (HMACSHA1 hmacSha1 = new HMACSHA1(keyBytes))
        {
            byte[] hmacHash = hmacSha1.ComputeHash(messageBytes);
            string hmacString = BitConverter.ToString(hmacHash).Replace("-", "").ToLowerInvariant();
            Console.WriteLine($"HMAC-SHA1:  {hmacString}");
        }

        // HMAC-SHA256
        using (HMACSHA256 hmacSha256 = new HMACSHA256(keyBytes))
        {
            byte[] hmacHash = hmacSha256.ComputeHash(messageBytes);
            string hmacString = BitConverter.ToString(hmacHash).Replace("-", "").ToLowerInvariant();
            Console.WriteLine($"HMAC-SHA256:{hmacString}");
        }

        // HMAC-SHA512
        using (HMACSHA512 hmacSha512 = new HMACSHA512(keyBytes))
        {
            byte[] hmacHash = hmacSha512.ComputeHash(messageBytes);
            string hmacString = BitConverter.ToString(hmacHash).Replace("-", "").ToLowerInvariant();
            Console.WriteLine($"HMAC-SHA512:{hmacString.Substring(0, 32)}...");
        }
    }

    // 4. Hash verification and comparison
    public static void HashVerificationExample()
    {
        Console.WriteLine("\n=== Hash Verification Example ===");

        string originalData = "Important data that needs integrity verification.";
        string tamperedData = "Important data that needs integrity verification.."; // Extra dot

        Console.WriteLine("Original Data Hashes:");
        byte[] originalBytes = Encoding.UTF8.GetBytes(originalData);

        using (SHA256 sha256 = SHA256.Create())
        {
            byte[] originalHash = sha256.ComputeHash(originalBytes);
            string originalHashString = BitConverter.ToString(originalHash).Replace("-", "").ToLowerInvariant();
            Console.WriteLine($"SHA-256: {originalHashString}");
        }

        Console.WriteLine("\nTampered Data Hashes:");
        byte[] tamperedBytes = Encoding.UTF8.GetBytes(tamperedData);

        using (SHA256 sha256 = SHA256.Create())
        {
            byte[] tamperedHash = sha256.ComputeHash(tamperedBytes);
            string tamperedHashString = BitConverter.ToString(tamperedHash).Replace("-", "").ToLowerInvariant();
            Console.WriteLine($"SHA-256: {tamperedHashString}");
        }

        // Verify if hashes match
        byte[] hash1, hash2;
        using (SHA256 sha256 = SHA256.Create())
        {
            hash1 = sha256.ComputeHash(Encoding.UTF8.GetBytes(originalData));
            hash2 = sha256.ComputeHash(Encoding.UTF8.GetBytes(tamperedData));
        }

        bool hashesMatch = hash1.Length == hash2.Length;
        if (hashesMatch)
        {
            for (int i = 0; i < hash1.Length; i++)
            {
                if (hash1[i] != hash2[i])
                {
                    hashesMatch = false;
                    break;
                }
            }
        }

        Console.WriteLine($"\nHash verification result: {(hashesMatch ? "MATCH - Data is intact" : "MISMATCH - Data has been tampered")}");
    }

    // 5. Password hashing and verification
    public static void PasswordHashingExample()
    {
        Console.WriteLine("\n=== Password Hashing Example ===");

        string password = "MySecurePassword123!";
        Console.WriteLine($"Original Password: {password}");

        // Generate salt
        byte[] salt = new byte[16];
        using (var rng = RandomNumberGenerator.Create())
        {
            rng.GetBytes(salt);
        }

        Console.WriteLine($"Generated Salt: {BitConverter.ToString(salt).Replace("-", "").ToLowerInvariant()}");

        // Hash password with salt using PBKDF2
        const int iterations = 10000;
        byte[] hash;

        using (var pbkdf2 = new Rfc2898DeriveBytes(password, salt, iterations, HashAlgorithmName.SHA256))
        {
            hash = pbkdf2.GetBytes(32); // 256-bit hash
        }

        // Combine salt and hash for storage
        byte[] hashBytes = new byte[48]; // 16 (salt) + 32 (hash)
        Array.Copy(salt, 0, hashBytes, 0, 16);
        Array.Copy(hash, 0, hashBytes, 16, 32);

        string storedHash = Convert.ToBase64String(hashBytes);
        Console.WriteLine($"Stored Hash: {storedHash}");

        // Verify password
        Console.WriteLine("\nPassword Verification:");
        VerifyPassword(password, storedHash, iterations);
        VerifyPassword("WrongPassword123!", storedHash, iterations);
    }

    private static void VerifyPassword(string enteredPassword, string storedHash, int iterations)
    {
        try
        {
            // Extract salt from stored hash
            byte[] hashBytes = Convert.FromBase64String(storedHash);
            byte[] salt = new byte[16];
            Array.Copy(hashBytes, 0, salt, 0, 16);

            // Compute hash of entered password
            byte[] enteredHash;
            using (var pbkdf2 = new Rfc2898DeriveBytes(enteredPassword, salt, iterations, HashAlgorithmName.SHA256))
            {
                enteredHash = pbkdf2.GetBytes(32);
            }

            // Compare hashes
            bool isValid = true;
            for (int i = 0; i < 32; i++)
            {
                if (hashBytes[i + 16] != enteredHash[i])
                {
                    isValid = false;
                    break;
                }
            }

            Console.WriteLine($"Password '{enteredPassword}': {(isValid ? "✓ Valid" : "✗ Invalid")}");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error verifying password: {ex.Message}");
        }
    }

    // 6. Streaming hash computation for large data
    public static void StreamingHashExample()
    {
        Console.WriteLine("\n=== Streaming Hash Example ===");

        // Create a large data stream
        string tempFilePath = "large_data.bin";
        using (var fileStream = File.Create(tempFilePath))
        using (var writer = new BinaryWriter(fileStream))
        {
            // Write some test data
            for (int i = 0; i < 1000; i++)
            {
                writer.Write(i); // Write integer
                writer.Write($"Data chunk {i:D4}".PadRight(50, ' ')); // Write string
                writer.Write((double)i * 1.5); // Write double
            }
        }

        Console.WriteLine($"Created large test file: {tempFilePath}");

        // Compute hash in streaming mode
        using (var fileStream = File.OpenRead(tempFilePath))
        using (SHA256 sha256 = SHA256.Create())
        {
            // Process file in chunks to demonstrate streaming
            byte[] buffer = new byte[8192];
            int bytesRead;
            long totalBytesRead = 0;

            while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) > 0)
            {
                sha256.TransformBlock(buffer, 0, bytesRead, null, 0);
                totalBytesRead += bytesRead;
            }

            // Finalize the hash computation
            sha256.TransformFinalBlock(new byte[0], 0, 0);
            byte[] hash = sha256.Hash;

            string hashString = BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
            Console.WriteLine($"Processed {totalBytesRead:N0} bytes");
            Console.WriteLine($"Streaming SHA-256: {hashString}");
        }

        // Compare with direct computation
        using (var fileStream = File.OpenRead(tempFilePath))
        using (SHA256 sha256 = SHA256.Create())
        {
            byte[] directHash = sha256.ComputeHash(fileStream);
            string directHashString = BitConverter.ToString(directHash).Replace("-", "").ToLowerInvariant();
            Console.WriteLine($"Direct SHA-256:   {directHashString}");
        }

        // Clean up
        File.Delete(tempFilePath);
    }

    public static void RunAllExamples()
    {
        Console.WriteLine("Hash Computation Examples");
        Console.WriteLine("==========================");

        BasicHashComputation();
        FileHashingExample();
        HMACExample();
        HashVerificationExample();
        PasswordHashingExample();
        StreamingHashExample();

        Console.WriteLine("\nHash computation examples completed!");
    }
}

💻 Cifrado Simétrico y Descifrado csharp

🟡 intermediate ⭐⭐⭐⭐

Implementación de cifrado simétrico usando AES, DES y TripleDES para confidencialidad de datos y comunicación segura

⏱️ 30 min 🏷️ csharp, encryption, aes, security, windows
Prerequisites: C# intermediate, Cryptography basics, Security concepts
using System;
using System.Security.Cryptography;
using System.Text;
using System.IO;

class SymmetricEncryption
{
    // 1. AES Encryption and Decryption
    public static void AESSample()
    {
        Console.WriteLine("=== AES Encryption and Decryption ===");

        string plainText = "This is a secret message that will be encrypted using AES algorithm.";
        Console.WriteLine($"Original Text: {plainText}");

        // Generate a random key and IV
        using (Aes aes = Aes.Create())
        {
            aes.KeySize = 256; // 256-bit key
            aes.BlockSize = 128; // 128-bit block
            aes.Mode = CipherMode.CBC;
            aes.Padding = PaddingMode.PKCS7;

            Console.WriteLine($"\nAES Configuration:");
            Console.WriteLine($"Key Size: {aes.KeySize} bits");
            Console.WriteLine($"Block Size: {aes.BlockSize} bits");
            Console.WriteLine($"Mode: {aes.Mode}");
            Console.WriteLine($"Padding: {aes.Padding}");

            // Convert key and IV to Base64 for display
            string keyBase64 = Convert.ToBase64String(aes.Key);
            string ivBase64 = Convert.ToBase64String(aes.IV);

            Console.WriteLine($"\nKey (Base64): {keyBase64}");
            Console.WriteLine($"IV (Base64):  {ivBase64}");

            // Encrypt the data
            byte[] encryptedData = EncryptStringToBytes_Aes(plainText, aes.Key, aes.IV);
            string encryptedBase64 = Convert.ToBase64String(encryptedData);

            Console.WriteLine($"\nEncrypted Data (Base64): {encryptedBase64}");
            Console.WriteLine($"Encrypted Size: {encryptedData.Length} bytes");

            // Decrypt the data
            string decryptedText = DecryptStringFromBytes_Aes(encryptedData, aes.Key, aes.IV);

            Console.WriteLine($"\nDecrypted Text: {decryptedText}");
            Console.WriteLine($"Decryption Successful: {plainText == decryptedText}");
        }
    }

    // 2. Compare different AES modes
    public static void AESModesComparison()
    {
        Console.WriteLine("\n=== AES Modes Comparison ===");

        string plainText = "This is a test message for comparing different AES modes of operation.";

        byte[] key = new byte[32]; // 256-bit key
        byte[] iv = new byte[16];  // 128-bit IV

        using (var rng = RandomNumberGenerator.Create())
        {
            rng.GetBytes(key);
            rng.GetBytes(iv);
        }

        Console.WriteLine($"Original Text: {plainText}");
        Console.WriteLine($"Key (Base64): {Convert.ToBase64String(key)}");
        Console.WriteLine($"IV (Base64):  {Convert.ToBase64String(iv)}");

        var modes = new CipherMode[] { CipherMode.CBC, CipherMode.ECB, CipherMode.CFB, CipherMode.OFB };

        foreach (var mode in modes)
        {
            try
            {
                Console.WriteLine($"\n{mode} Mode:");

                using (Aes aes = Aes.Create())
                {
                    aes.Key = key;
                    aes.IV = iv;
                    aes.Mode = mode;
                    aes.Padding = PaddingMode.PKCS7;

                    // ECB mode doesn't use IV
                    if (mode == CipherMode.ECB)
                    {
                        aes.IV = new byte[16]; // Zero IV for ECB
                    }

                    // Encrypt
                    ICryptoTransform encryptor = aes.CreateEncryptor();
                    byte[] encrypted = EncryptWithTransform(plainText, encryptor);
                    string encryptedBase64 = Convert.ToBase64String(encrypted);
                    Console.WriteLine($"  Encrypted: {encryptedBase64.Substring(0, Math.Min(64, encryptedBase64.Length))}...");

                    // Decrypt
                    ICryptoTransform decryptor = aes.CreateDecryptor();
                    string decrypted = DecryptWithTransform(encrypted, decryptor);
                    Console.WriteLine($"  Decrypted: {decrypted}");
                    Console.WriteLine($"  Success: {plainText == decrypted}");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"  Error with {mode}: {ex.Message}");
            }
        }
    }

    // 3. DES and TripleDES examples
    public static void DESAndTripleDESSample()
    {
        Console.WriteLine("\n=== DES and TripleDES Examples ===");

        string plainText = "This message will be encrypted with DES and TripleDES.";
        Console.WriteLine($"Original Text: {plainText}");

        // DES Example (not recommended for production)
        Console.WriteLine("\n--- DES Encryption (56-bit key) ---");
        using (DES des = DES.Create())
        {
            des.Mode = CipherMode.CBC;
            des.Padding = PaddingMode.PKCS7;

            Console.WriteLine($"DES Key (Base64): {Convert.ToBase64String(des.Key)}");
            Console.WriteLine($"DES IV (Base64):  {Convert.ToBase64String(des.IV)}");

            byte[] desEncrypted = EncryptStringToBytes_DES(plainText, des.Key, des.IV);
            string desEncryptedBase64 = Convert.ToBase64String(desEncrypted);
            Console.WriteLine($"DES Encrypted: {desEncryptedBase64}");

            string desDecrypted = DecryptStringFromBytes_DES(desEncrypted, des.Key, des.IV);
            Console.WriteLine($"DES Decrypted: {desDecrypted}");
            Console.WriteLine($"DES Success: {plainText == desDecrypted}");
        }

        // TripleDES Example
        Console.WriteLine("\n--- TripleDES Encryption (168-bit key) ---");
        using (TripleDES tripleDes = TripleDES.Create())
        {
            tripleDes.Mode = CipherMode.CBC;
            tripleDes.Padding = PaddingMode.PKCS7;

            Console.WriteLine($"TripleDES Key (Base64): {Convert.ToBase64String(tripleDes.Key)}");
            Console.WriteLine($"TripleDES IV (Base64):  {Convert.ToBase64String(tripleDes.IV)}");

            byte[] tripleDesEncrypted = EncryptStringToBytes_TripleDES(plainText, tripleDes.Key, tripleDes.IV);
            string tripleDesEncryptedBase64 = Convert.ToBase64String(tripleDesEncrypted);
            Console.WriteLine($"TripleDES Encrypted: {tripleDesEncryptedBase64}");

            string tripleDesDecrypted = DecryptStringFromBytes_TripleDES(tripleDesEncrypted, tripleDes.Key, tripleDes.IV);
            Console.WriteLine($"TripleDES Decrypted: {tripleDesDecrypted}");
            Console.WriteLine($"TripleDES Success: {plainText == tripleDesDecrypted}");
        }
    }

    // 4. File encryption and decryption
    public static void FileEncryptionExample()
    {
        Console.WriteLine("\n=== File Encryption Example ===");

        string originalFilePath = "original_file.txt";
        string encryptedFilePath = "encrypted_file.bin";
        string decryptedFilePath = "decrypted_file.txt";

        // Create original file
        string fileContent = @"This is the content of our test file.
It contains multiple lines of text.
We will encrypt this file using AES.
After encryption, we will decrypt it back.
The content should remain unchanged.";

        File.WriteAllText(originalFilePath, fileContent);
        Console.WriteLine($"Created original file: {originalFilePath}");
        Console.WriteLine($"File content:\n{fileContent}");

        // Generate key and IV
        byte[] key, iv;
        using (Aes aes = Aes.Create())
        {
            key = aes.Key;
            iv = aes.IV;
        }

        Console.WriteLine($"\nUsing AES key: {Convert.ToBase64String(key)}");
        Console.WriteLine($"Using AES IV:  {Convert.ToBase64String(iv)}");

        // Encrypt file
        EncryptFile(originalFilePath, encryptedFilePath, key, iv);
        Console.WriteLine($"\nFile encrypted to: {encryptedFilePath}");

        // Show encrypted file info
        FileInfo originalInfo = new FileInfo(originalFilePath);
        FileInfo encryptedInfo = new FileInfo(encryptedFilePath);
        Console.WriteLine($"Original file size: {originalInfo.Length} bytes");
        Console.WriteLine($"Encrypted file size: {encryptedInfo.Length} bytes");

        // Decrypt file
        DecryptFile(encryptedFilePath, decryptedFilePath, key, iv);
        Console.WriteLine($"\nFile decrypted to: {decryptedFilePath}");

        // Verify decrypted content
        string decryptedContent = File.ReadAllText(decryptedFilePath);
        Console.WriteLine($"\nDecrypted content:\n{decryptedContent}");
        Console.WriteLine($"Content matches original: {fileContent == decryptedContent}");

        // Clean up
        File.Delete(originalFilePath);
        File.Delete(encryptedFilePath);
        File.Delete(decryptedFilePath);
    }

    // 5. Key derivation and management
    public static void KeyDerivationExample()
    {
        Console.WriteLine("\n=== Key Derivation Example ===");

        string password = "MySecurePassword123!";
        string salt = "RandomSaltValue@#$";

        Console.WriteLine($"Password: {password}");
        Console.WriteLine($"Salt: {salt}");

        // Derive key using Rfc2898DeriveBytes (PBKDF2)
        using (var pbkdf2 = new Rfc2898DeriveBytes(password, Encoding.UTF8.GetBytes(salt), 10000))
        {
            // Derive 256-bit key for AES
            byte[] aesKey = pbkdf2.GetBytes(32); // 32 bytes = 256 bits
            Console.WriteLine($"\nDerived AES Key (Base64): {Convert.ToBase64String(aesKey)}");
            Console.WriteLine($"Key length: {aesKey.Length * 8} bits");

            // Test encryption with derived key
            string testMessage = "This message is encrypted with a key derived from a password.";
            byte[] iv = new byte[16];
            using (var rng = RandomNumberGenerator.Create())
            {
                rng.GetBytes(iv);
            }

            using (Aes aes = Aes.Create())
            {
                aes.Key = aesKey;
                aes.IV = iv;

                byte[] encrypted = EncryptStringToBytes_Aes(testMessage, aes.Key, aes.IV);
                string decrypted = DecryptStringFromBytes_Aes(encrypted, aes.Key, aes.IV);

                Console.WriteLine($"\nTest with derived key:");
                Console.WriteLine($"Original: {testMessage}");
                Console.WriteLine($"Decrypted: {decrypted}");
                Console.WriteLine($"Success: {testMessage == decrypted}");
            }
        }
    }

    // 6. Stream-based encryption
    public static void StreamEncryptionExample()
    {
        Console.WriteLine("\n=== Stream-based Encryption Example ===");

        string testText = "This is a test for stream-based encryption. ";
        testText = string.Concat(Enumerable.Repeat(testText, 100)); // Repeat 100 times

        Console.WriteLine($"Original text length: {testText.Length} characters");
        Console.WriteLine($"Original text sample: {testText.Substring(0, 50)}...");

        // Generate key and IV
        byte[] key, iv;
        using (Aes aes = Aes.Create())
        {
            key = aes.Key;
            iv = aes.IV;
        }

        // Encrypt using streams
        byte[] encryptedData;
        using (var memoryStream = new MemoryStream())
        using (var aes = Aes.Create())
        {
            aes.Key = key;
            aes.IV = iv;

            using (var cryptoStream = new CryptoStream(memoryStream, aes.CreateEncryptor(), CryptoStreamMode.Write))
            using (var streamWriter = new StreamWriter(cryptoStream))
            {
                streamWriter.Write(testText);
            }

            encryptedData = memoryStream.ToArray();
        }

        Console.WriteLine($"\nEncrypted data length: {encryptedData.Length} bytes");
        Console.WriteLine($"Encryption ratio: {(double)encryptedData.Length / testText.Length:F2}");

        // Decrypt using streams
        string decryptedText;
        using (var memoryStream = new MemoryStream(encryptedData))
        using (var aes = Aes.Create())
        {
            aes.Key = key;
            aes.IV = iv;

            using (var cryptoStream = new CryptoStream(memoryStream, aes.CreateDecryptor(), CryptoStreamMode.Read))
            using (var streamReader = new StreamReader(cryptoStream))
            {
                decryptedText = streamReader.ReadToEnd();
            }
        }

        Console.WriteLine($"\nDecrypted text length: {decryptedText.Length} characters");
        Console.WriteLine($"Decrypted text sample: {decryptedText.Substring(0, 50)}...");
        Console.WriteLine($"Decryption successful: {testText == decryptedText}");
    }

    // Helper methods for encryption/decryption
    private static byte[] EncryptStringToBytes_Aes(string plainText, byte[] Key, byte[] IV)
    {
        using (Aes aesAlg = Aes.Create())
        {
            aesAlg.Key = Key;
            aesAlg.IV = IV;

            ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);

            using (var msEncrypt = new MemoryStream())
            {
                using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                {
                    using (var swEncrypt = new StreamWriter(csEncrypt))
                    {
                        swEncrypt.Write(plainText);
                    }
                    return msEncrypt.ToArray();
                }
            }
        }
    }

    private static string DecryptStringFromBytes_Aes(byte[] cipherText, byte[] Key, byte[] IV)
    {
        using (Aes aesAlg = Aes.Create())
        {
            aesAlg.Key = Key;
            aesAlg.IV = IV;

            ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);

            using (var msDecrypt = new MemoryStream(cipherText))
            {
                using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                {
                    using (var srDecrypt = new StreamReader(csDecrypt))
                    {
                        return srDecrypt.ReadToEnd();
                    }
                }
            }
        }
    }

    private static byte[] EncryptWithTransform(string plainText, ICryptoTransform encryptor)
    {
        using (var memoryStream = new MemoryStream())
        using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
        {
            byte[] plainBytes = Encoding.UTF8.GetBytes(plainText);
            cryptoStream.Write(plainBytes, 0, plainBytes.Length);
            cryptoStream.FlushFinalBlock();
            return memoryStream.ToArray();
        }
    }

    private static string DecryptWithTransform(byte[] cipherText, ICryptoTransform decryptor)
    {
        using (var memoryStream = new MemoryStream(cipherText))
        using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
        using (var streamReader = new StreamReader(cryptoStream))
        {
            return streamReader.ReadToEnd();
        }
    }

    private static byte[] EncryptStringToBytes_DES(string plainText, byte[] Key, byte[] IV)
    {
        using (DES desAlg = DES.Create())
        {
            desAlg.Key = Key;
            desAlg.IV = IV;

            ICryptoTransform encryptor = desAlg.CreateEncryptor(desAlg.Key, desAlg.IV);

            using (var msEncrypt = new MemoryStream())
            using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
            using (var swEncrypt = new StreamWriter(csEncrypt))
            {
                swEncrypt.Write(plainText);
                return msEncrypt.ToArray();
            }
        }
    }

    private static string DecryptStringFromBytes_DES(byte[] cipherText, byte[] Key, byte[] IV)
    {
        using (DES desAlg = DES.Create())
        {
            desAlg.Key = Key;
            desAlg.IV = IV;

            ICryptoTransform decryptor = desAlg.CreateDecryptor(desAlg.Key, desAlg.IV);

            using (var msDecrypt = new MemoryStream(cipherText))
            using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
            using (var srDecrypt = new StreamReader(csDecrypt))
            {
                return srDecrypt.ReadToEnd();
            }
        }
    }

    private static byte[] EncryptStringToBytes_TripleDES(string plainText, byte[] Key, byte[] IV)
    {
        using (TripleDES tripleDesAlg = TripleDES.Create())
        {
            tripleDesAlg.Key = Key;
            tripleDesAlg.IV = IV;

            ICryptoTransform encryptor = tripleDesAlg.CreateEncryptor(tripleDesAlg.Key, tripleDesAlg.IV);

            using (var msEncrypt = new MemoryStream())
            using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
            using (var swEncrypt = new StreamWriter(csEncrypt))
            {
                swEncrypt.Write(plainText);
                return msEncrypt.ToArray();
            }
        }
    }

    private static string DecryptStringFromBytes_TripleDES(byte[] cipherText, byte[] Key, byte[] IV)
    {
        using (TripleDES tripleDesAlg = TripleDES.Create())
        {
            tripleDesAlg.Key = Key;
            tripleDesAlg.IV = IV;

            ICryptoTransform decryptor = tripleDesAlg.CreateDecryptor(tripleDesAlg.Key, tripleDesAlg.IV);

            using (var msDecrypt = new MemoryStream(cipherText))
            using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
            using (var srDecrypt = new StreamReader(csDecrypt))
            {
                return srDecrypt.ReadToEnd();
            }
        }
    }

    private static void EncryptFile(string inputFile, string outputFile, byte[] key, byte[] iv)
    {
        using (Aes aes = Aes.Create())
        {
            aes.Key = key;
            aes.IV = iv;

            using (var inputStream = File.OpenRead(inputFile))
            using (var outputStream = File.Create(outputFile))
            using (var cryptoStream = new CryptoStream(outputStream, aes.CreateEncryptor(), CryptoStreamMode.Write))
            {
                inputStream.CopyTo(cryptoStream);
            }
        }
    }

    private static void DecryptFile(string inputFile, string outputFile, byte[] key, byte[] iv)
    {
        using (Aes aes = Aes.Create())
        {
            aes.Key = key;
            aes.IV = iv;

            using (var inputStream = File.OpenRead(inputFile))
            using (var cryptoStream = new CryptoStream(inputStream, aes.CreateDecryptor(), CryptoStreamMode.Read))
            using (var outputStream = File.Create(outputFile))
            {
                cryptoStream.CopyTo(outputStream);
            }
        }
    }

    public static void RunAllExamples()
    {
        Console.WriteLine("Symmetric Encryption Examples");
        Console.WriteLine("===============================");

        AESSample();
        AESModesComparison();
        DESAndTripleDESSample();
        FileEncryptionExample();
        KeyDerivationExample();
        StreamEncryptionExample();

        Console.WriteLine("\nSymmetric encryption examples completed!");
    }
}

💻 Firmas Digitales y Criptografía Asimétrica csharp

🔴 complex ⭐⭐⭐⭐⭐

Implementación de firmas digitales usando RSA para autenticación de datos, no repudio e intercambio seguro de claves

⏱️ 35 min 🏷️ csharp, rsa, digital-signature, cryptography, windows
Prerequisites: C# advanced, Asymmetric cryptography, PKI concepts
using System;
using System.Security.Cryptography;
using System.Text;
using System.IO;

class DigitalSignatures
{
    // 1. RSA Key Generation and Management
    public static void RSAKeyGenerationExample()
    {
        Console.WriteLine("=== RSA Key Generation Example ===");

        // Generate RSA key pair
        using (RSA rsa = RSA.Create())
        {
            // Key size options: 1024, 2048, 3072, 4096
            rsa.KeySize = 2048;

            Console.WriteLine($"RSA Key Size: {rsa.KeySize} bits");
            Console.WriteLine($"Public Key Format: {rsa.PublicKey.GetType().Name}");

            // Export public key
            byte[] publicKeyBytes = rsa.ExportRSAPublicKey();
            string publicKeyBase64 = Convert.ToBase64String(publicKeyBytes);
            Console.WriteLine($"\nPublic Key (Base64): {publicKeyBase64.Substring(0, 64)}...({publicKeyBase64.Length} chars)");

            // Export private key
            byte[] privateKeyBytes = rsa.ExportRSAPrivateKey();
            string privateKeyBase64 = Convert.ToBase64String(privateKeyBytes);
            Console.WriteLine($"Private Key (Base64): {privateKeyBase64.Substring(0, 64)}...({privateKeyBase64.Length} chars)");

            // Export with different formats
            var publicKey = rsa.ExportParameters(false); // false = public only
            var privateKey = rsa.ExportParameters(true);  // true = include private

            Console.WriteLine($"\nPublic Key Parameters:");
            Console.WriteLine($"  Modulus: {publicKey.Modulus.Length} bytes");
            Console.WriteLine($"  Exponent: {publicKey.Exponent.Length} bytes");

            Console.WriteLine($"\nPrivate Key Parameters:");
            Console.WriteLine($"  Modulus: {privateKey.Modulus.Length} bytes");
            Console.WriteLine($"  Exponent: {privateKey.Exponent.Length} bytes");
            Console.WriteLine($"  D: {privateKey.D?.Length ?? 0} bytes");
            Console.WriteLine($"  P: {privateKey.P?.Length ?? 0} bytes");
            Console.WriteLine($"  Q: {privateKey.Q?.Length ?? 0} bytes");

            // Save keys to files
            File.WriteAllText("public_key.pem", ExportToPEM(publicKeyBytes, "PUBLIC KEY"));
            File.WriteAllText("private_key.pem", ExportToPEM(privateKeyBytes, "PRIVATE KEY"));
            Console.WriteLine($"\nKeys saved to: public_key.pem, private_key.pem");
        }
    }

    // 2. Digital Signature Creation and Verification
    public static void DigitalSignatureExample()
    {
        Console.WriteLine("\n=== Digital Signature Example ===");

        string message = "This is an important document that needs to be authenticated and verified for integrity.";
        Console.WriteLine($"Original Message: {message}");

        // Generate key pair
        using (RSA rsa = RSA.Create(2048))
        {
            // Create signature
            byte[] signature = CreateDigitalSignature(message, rsa);
            string signatureBase64 = Convert.ToBase64String(signature);
            Console.WriteLine($"\nDigital Signature (Base64): {signatureBase64.Substring(0, 64)}...");
            Console.WriteLine($"Signature Size: {signature.Length} bytes");

            // Verify signature with original key
            bool isValid = VerifyDigitalSignature(message, signature, rsa);
            Console.WriteLine($"\nSignature Verification (Original): {isValid}");

            // Verify with different message (should fail)
            string tamperedMessage = message + " [MODIFIED]";
            bool isTamperedValid = VerifyDigitalSignature(tamperedMessage, signature, rsa);
            Console.WriteLine($"Signature Verification (Tampered): {isTamperedValid}");

            // Test with different key (should fail)
            using (RSA differentRsa = RSA.Create(2048))
            {
                bool isDifferentKeyValid = VerifyDigitalSignature(message, signature, differentRsa);
                Console.WriteLine($"Signature Verification (Different Key): {isDifferentKeyValid}");
            }
        }
    }

    // 3. RSA Encryption and Decryption
    public static void RSAEncryptionExample()
    {
        Console.WriteLine("\n=== RSA Encryption and Decryption ===");

        string plaintext = "This is a secret message encrypted with RSA.";
        Console.WriteLine($"Original Message: {plaintext}");
        Console.WriteLine($"Message Length: {Encoding.UTF8.GetBytes(plaintext).Length} bytes");

        // Generate key pair
        using (RSA rsa = RSA.Create(2048))
        {
            try
            {
                // Encrypt with public key
                byte[] encryptedData = RSAEncrypt(plaintext, rsa.ExportRSAPublicKey());
                string encryptedBase64 = Convert.ToBase64String(encryptedData);
                Console.WriteLine($"\nEncrypted Data (Base64): {encryptedBase64.Substring(0, 64)}...");
                Console.WriteLine($"Encrypted Size: {encryptedData.Length} bytes");

                // Decrypt with private key
                string decryptedText = RSADecrypt(encryptedData, rsa.ExportRSAPrivateKey());
                Console.WriteLine($"\nDecrypted Message: {decryptedText}");
                Console.WriteLine($"Decryption Successful: {plaintext == decryptedText}");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error: {ex.Message}");
                Console.WriteLine("Note: RSA can only encrypt data smaller than key size - 42 bytes for OAEP padding");

                // Try with shorter message
                string shortMessage = "Short";
                Console.WriteLine($"\nTrying with shorter message: '{shortMessage}'");

                try
                {
                    byte[] encryptedShort = RSAEncrypt(shortMessage, rsa.ExportRSAPublicKey());
                    string decryptedShort = RSADecrypt(encryptedShort, rsa.ExportRSAPrivateKey());
                    Console.WriteLine($"Short message encryption successful: {shortMessage == decryptedShort}");
                }
                catch (Exception ex2)
                {
                    Console.WriteLine($"Short message failed: {ex2.Message}");
                }
            }
        }
    }

    // 4. Hybrid Encryption (RSA + AES)
    public static void HybridEncryptionExample()
    {
        Console.WriteLine("\n=== Hybrid Encryption Example ===");

        string longMessage = "This is a long message that demonstrates hybrid encryption. " +
                           "We use RSA to encrypt the AES key, and AES to encrypt the actual data. " +
                           "This allows us to encrypt large amounts of data securely while using RSA's " +
                           "public key infrastructure for key exchange.";

        Console.WriteLine($"Original Message: {longMessage}");
        Console.WriteLine($"Message Length: {Encoding.UTF8.GetBytes(longMessage).Length} bytes");

        // Generate RSA key pair
        using (RSA rsa = RSA.Create(2048))
        {
            // Encrypt using hybrid approach
            var encryptedPackage = HybridEncrypt(longMessage, rsa.ExportRSAPublicKey());

            Console.WriteLine($"\nHybrid Encryption Package:");
            Console.WriteLine($"  Encrypted AES Key Size: {encryptedPackage.EncryptedKey.Length} bytes");
            Console.WriteLine($"  IV Size: {encryptedPackage.IV.Length} bytes");
            Console.WriteLine($"  Encrypted Data Size: {encryptedPackage.EncryptedData.Length} bytes");
            Console.WriteLine($"  Total Size: {encryptedPackage.GetTotalSize()} bytes");

            // Decrypt using hybrid approach
            string decryptedMessage = HybridDecrypt(encryptedPackage, rsa.ExportRSAPrivateKey());

            Console.WriteLine($"\nDecrypted Message: {decryptedMessage}");
            Console.WriteLine($"Hybrid Decryption Successful: {longMessage == decryptedMessage}");
        }
    }

    // 5. Certificate-based Signing
    public static void CertificateSigningExample()
    {
        Console.WriteLine("\n=== Certificate-based Signing Example ===");

        try
        {
            // Create self-signed certificate for demonstration
            string subjectName = "CN=Demo Certificate, O=Demo Company, C=US";

            using (var rsa = RSA.Create(2048))
            {
                var certificateRequest = new CertificateRequest(
                    subjectName,
                    rsa,
                    HashAlgorithmName.SHA256,
                    RSASignaturePadding.Pkcs1);

                // Add extensions
                certificateRequest.CertificateExtensions.Add(
                    new System.Security.Cryptography.X509Certificates.X509BasicConstraintsExtension(false, false, 0, false));

                certificateRequest.CertificateExtensions.Add(
                    new System.Security.Cryptography.X509Certificates.X509KeyUsageExtension(
                        System.Security.Cryptography.X509Certificates.X509KeyUsageFlags.DigitalSignature |
                        System.Security.Cryptography.X509Certificates.X509KeyUsageFlags.NonRepudiation,
                        false));

                // Create self-signed certificate
                var certificate = certificateRequest.CreateSelfSigned(
                    DateTimeOffset.Now.AddDays(-1),
                    DateTimeOffset.Now.AddDays(365));

                Console.WriteLine($"Created certificate: {certificate.Subject}");
                Console.WriteLine($"Valid from: {certificate.NotBefore:yyyy-MM-dd}");
                Console.WriteLine($"Valid until: {certificate.NotAfter:yyyy-MM-dd}");
                Console.WriteLine($"Thumbprint: {certificate.Thumbprint}");

                // Sign data with certificate's private key
                string document = "This document is signed with a digital certificate.";
                byte[] documentBytes = Encoding.UTF8.GetBytes(document);

                byte[] signature;
                using (var privateKey = certificate.GetRSAPrivateKey())
                {
                    signature = privateKey.SignData(documentBytes, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
                }

                Console.WriteLine($"\nDocument signed with certificate.");
                Console.WriteLine($"Signature Size: {signature.Length} bytes");

                // Verify with certificate's public key
                using (var publicKey = certificate.GetRSAPublicKey())
                {
                    bool isValid = publicKey.VerifyData(
                        documentBytes,
                        signature,
                        HashAlgorithmName.SHA256,
                        RSASignaturePadding.Pkcs1);

                    Console.WriteLine($"Signature verification: {isValid}");
                }

                // Export certificate
                byte[] certBytes = certificate.Export(System.Security.Cryptography.X509Certificates.X509ContentType.Cert);
                File.WriteAllBytes("demo_certificate.cer", certBytes);
                Console.WriteLine("\nCertificate exported to: demo_certificate.cer");
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Certificate creation failed: {ex.Message}");
            Console.WriteLine("This might require elevated privileges or specific system configuration.");
        }
    }

    // 6. Key Exchange Protocol
    public static void KeyExchangeExample()
    {
        Console.WriteLine("\n=== Key Exchange Protocol Example ===");

        // Alice generates her key pair
        using (RSA aliceRsa = RSA.Create(2048))
        {
            Console.WriteLine("Alice generates RSA key pair");

            // Bob generates his key pair
            using (RSA bobRsa = RSA.Create(2048))
            {
                Console.WriteLine("Bob generates RSA key pair");

                // Alice wants to send a secret message to Bob
                string secretMessage = "This is a secret message from Alice to Bob.";
                Console.WriteLine($"\nAlice's message: {secretMessage}");

                // Alice encrypts the message with Bob's public key
                byte[] encryptedForBob = RSAEncrypt(secretMessage, bobRsa.ExportRSAPublicKey());
                Console.WriteLine("Alice encrypts message with Bob's public key");

                // Bob decrypts with his private key
                string decryptedByBob = RSADecrypt(encryptedForBob, bobRsa.ExportRSAPrivateKey());
                Console.WriteLine($"Bob decrypts message: {decryptedByBob}");

                // Bob signs a response with his private key
                string bobResponse = "Message received. Thank you, Alice!";
                byte[] bobSignature = CreateDigitalSignature(bobResponse, bobRsa);
                Console.WriteLine($"\nBob signs response: {bobResponse}");

                // Alice verifies Bob's signature with his public key
                bool aliceVerifies = VerifyDigitalSignature(bobResponse, bobSignature, bobRsa.ExportRSAPublicKey());
                Console.WriteLine($"Alice verifies Bob's signature: {aliceVerifies}");

                // Demonstrate man-in-the-middle protection
                Console.WriteLine("\n--- Man-in-the-Middle Protection ---");

                // Eve tries to tamper with the message
                string tamperedMessage = "This is a tampered message!";
                bool eveVerification = VerifyDigitalSignature(tamperedMessage, bobSignature, bobRsa.ExportRSAPublicKey());
                Console.WriteLine($"Eve's tampered message verification: {eveVerification} (should be false)");
            }
        }
    }

    // Helper methods
    private static byte[] CreateDigitalSignature(string message, RSA rsa)
    {
        byte[] messageBytes = Encoding.UTF8.GetBytes(message);
        return rsa.SignData(messageBytes, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
    }

    private static bool VerifyDigitalSignature(string message, byte[] signature, RSA rsa)
    {
        byte[] messageBytes = Encoding.UTF8.GetBytes(message);
        return rsa.VerifyData(messageBytes, signature, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
    }

    private static bool VerifyDigitalSignature(string message, byte[] signature, byte[] publicKeyBytes)
    {
        using (RSA rsa = RSA.Create())
        {
            rsa.ImportRSAPublicKey(publicKeyBytes, out _);
            return VerifyDigitalSignature(message, signature, rsa);
        }
    }

    private static byte[] RSAEncrypt(string plaintext, byte[] publicKeyBytes)
    {
        using (RSA rsa = RSA.Create())
        {
            rsa.ImportRSAPublicKey(publicKeyBytes, out _);
            byte[] plaintextBytes = Encoding.UTF8.GetBytes(plaintext);
            return rsa.Encrypt(plaintextBytes, RSAEncryptionPadding.OaepSHA256);
        }
    }

    private static string RSADecrypt(byte[] ciphertext, byte[] privateKeyBytes)
    {
        using (RSA rsa = RSA.Create())
        {
            rsa.ImportRSAPrivateKey(privateKeyBytes, out _);
            byte[] decryptedBytes = rsa.Decrypt(ciphertext, RSAEncryptionPadding.OaepSHA256);
            return Encoding.UTF8.GetString(decryptedBytes);
        }
    }

    private static string ExportToPEM(byte[] data, string header)
    {
        StringBuilder sb = new StringBuilder();
        sb.AppendLine($"-----BEGIN {header}-----");
        string base64 = Convert.ToBase64String(data);

        for (int i = 0; i < base64.Length; i += 64)
        {
            sb.AppendLine(base64.Substring(i, Math.Min(64, base64.Length - i)));
        }

        sb.AppendLine($"-----END {header}-----");
        return sb.ToString();
    }

    private class EncryptedPackage
    {
        public byte[] EncryptedKey { get; set; }
        public byte[] IV { get; set; }
        public byte[] EncryptedData { get; set; }

        public int GetTotalSize()
        {
            return EncryptedKey.Length + IV.Length + EncryptedData.Length;
        }
    }

    private static EncryptedPackage HybridEncrypt(string plaintext, byte[] rsaPublicKey)
    {
        // Generate random AES key and IV
        byte[] aesKey = new byte[32]; // 256-bit key
        byte[] iv = new byte[16];     // 128-bit IV

        using (var rng = RandomNumberGenerator.Create())
        {
            rng.GetBytes(aesKey);
            rng.GetBytes(iv);
        }

        // Encrypt data with AES
        byte[] encryptedData;
        using (Aes aes = Aes.Create())
        {
            aes.Key = aesKey;
            aes.IV = iv;

            using (var memoryStream = new MemoryStream())
            using (var cryptoStream = new CryptoStream(memoryStream, aes.CreateEncryptor(), CryptoStreamMode.Write))
            {
                byte[] plaintextBytes = Encoding.UTF8.GetBytes(plaintext);
                cryptoStream.Write(plaintextBytes, 0, plaintextBytes.Length);
                cryptoStream.FlushFinalBlock();
                encryptedData = memoryStream.ToArray();
            }
        }

        // Encrypt AES key with RSA
        using (RSA rsa = RSA.Create())
        {
            rsa.ImportRSAPublicKey(rsaPublicKey, out _);
            byte[] encryptedKey = rsa.Encrypt(aesKey, RSAEncryptionPadding.OaepSHA256);

            return new EncryptedPackage
            {
                EncryptedKey = encryptedKey,
                IV = iv,
                EncryptedData = encryptedData
            };
        }
    }

    private static string HybridDecrypt(EncryptedPackage package, byte[] rsaPrivateKey)
    {
        // Decrypt AES key with RSA
        byte[] aesKey;
        using (RSA rsa = RSA.Create())
        {
            rsa.ImportRSAPrivateKey(rsaPrivateKey, out _);
            aesKey = rsa.Decrypt(package.EncryptedKey, RSAEncryptionPadding.OaepSHA256);
        }

        // Decrypt data with AES
        using (Aes aes = Aes.Create())
        {
            aes.Key = aesKey;
            aes.IV = package.IV;

            using (var memoryStream = new MemoryStream(package.EncryptedData))
            using (var cryptoStream = new CryptoStream(memoryStream, aes.CreateDecryptor(), CryptoStreamMode.Read))
            using (var streamReader = new StreamReader(cryptoStream))
            {
                return streamReader.ReadToEnd();
            }
        }
    }

    public static void RunAllExamples()
    {
        Console.WriteLine("Digital Signatures and Asymmetric Cryptography Examples");
        Console.WriteLine("=======================================================");

        RSAKeyGenerationExample();
        DigitalSignatureExample();
        RSAEncryptionExample();
        HybridEncryptionExample();
        CertificateSigningExample();
        KeyExchangeExample();

        Console.WriteLine("\nDigital signatures and asymmetric cryptography examples completed!");
    }
}