.NET C#:使用对称/非对称加密算法对字符串进行加密与解密详解

加密方式简介 —— 对称 vs 非对称

  • 对称加密(Symmetric Encryption):使用同一个密钥(secret key)对数据进行加密和解密。优点是效率高,适合加密大量数据。常用算法有 AES(高级加密标准)、DES、3DES 等。
  • 非对称加密(Asymmetric Encryption):使用一对密钥:公钥(public key)和私钥(private key)。用公钥加密的数据只能用对应私钥解密,反之亦然。适用于少量数据,如密钥传输、数字签名等场景。常用算法有 RSA。

在实际应用中,通常将两者结合,以兼顾安全性与性能 —— 用对称加密处理大块数据,用非对称加密保护对称密钥/IV,这种“混合加密”(hybrid encryption)是一个常见且推荐的做法。

在 .NET/C# 中如何使用对称加密(AES)

以下是一个使用 AES 对字符串进行加密、解密的基本示例。

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

public class AesStringEncryption
{
    public static byte[] EncryptStringToBytes_Aes(string plainText, byte[] Key, byte[] IV)
    {
        if (plainText == null || plainText.Length <= 0)
            throw new ArgumentNullException(nameof(plainText));
        if (Key == null || Key.Length <= 0)
            throw new ArgumentNullException(nameof(Key));
        if (IV == null || IV.Length <= 0)
            throw new ArgumentNullException(nameof(IV));

        using (Aes aesAlg = Aes.Create())
        {
            aesAlg.Key = Key;
            aesAlg.IV = IV;

            ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
            using (MemoryStream msEncrypt = new MemoryStream())
            {
                using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                {
                    swEncrypt.Write(plainText);
                }
                return msEncrypt.ToArray();
            }
        }
    }

    public static string DecryptStringFromBytes_Aes(byte[] cipherText, byte[] Key, byte[] IV)
    {
        if (cipherText == null || cipherText.Length <= 0)
            throw new ArgumentNullException(nameof(cipherText));
        if (Key == null || Key.Length <= 0)
            throw new ArgumentNullException(nameof(Key));
        if (IV == null || IV.Length <= 0)
            throw new ArgumentNullException(nameof(IV));

        using (Aes aesAlg = Aes.Create())
        {
            aesAlg.Key = Key;
            aesAlg.IV = IV;

            ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
            using (MemoryStream msDecrypt = new MemoryStream(cipherText))
            using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
            using (StreamReader srDecrypt = new StreamReader(csDecrypt))
            {
                return srDecrypt.ReadToEnd();
            }
        }
    }
}

// 使用示例
class Program
{
    public static void Main()
    {
        string original = "这是需要加密的字符串。";
        using (Aes aes = Aes.Create())
        {
            byte[] encrypted = AesStringEncryption.EncryptStringToBytes_Aes(original, aes.Key, aes.IV);
            string decrypted = AesStringEncryption.DecryptStringFromBytes_Aes(encrypted, aes.Key, aes.IV);

            Console.WriteLine($"Encrypted(Base64): {Convert.ToBase64String(encrypted)}");
            Console.WriteLine($"Decrypted: {decrypted}");
        }
    }
}

上述代码中,aes.Keyaes.IV 由系统随机生成,保证安全性。解密时必须使用相同的 Key 和 IV。

在 .NET/C# 中如何使用非对称加密(RSA)对字符串进行加解密

使用 RSA 加密字符串也很直接,但需要注意 RSA 通常用于少量数据,否则效率低下。以下为简化示例:

using System;
using System.Security.Cryptography;
using System.Text;

public class RsaStringEncryption
{
    public static byte[] Encrypt(string plainText, RSAParameters publicKey)
    {
        using (var rsa = RSA.Create())
        {
            rsa.ImportParameters(publicKey);
            return rsa.Encrypt(Encoding.UTF8.GetBytes(plainText), RSAEncryptionPadding.OaepSHA256);
        }
    }

    public static string Decrypt(byte[] cipherBytes, RSAParameters privateKey)
    {
        using (var rsa = RSA.Create())
        {
            rsa.ImportParameters(privateKey);
            byte[] decryptedBytes = rsa.Decrypt(cipherBytes, RSAEncryptionPadding.OaepSHA256);
            return Encoding.UTF8.GetString(decryptedBytes);
        }
    }
}

// 使用示例
var rsa = RSA.Create(2048);
var publicKey = rsa.ExportParameters(false);
var privateKey = rsa.ExportParameters(true);

string original = "Hello RSA 加密字符串";
byte[] encrypted = RsaStringEncryption.Encrypt(original, publicKey);
string decrypted = RsaStringEncryption.Decrypt(encrypted, privateKey);

Console.WriteLine($"Encrypted(Base64): {Convert.ToBase64String(encrypted)}");
Console.WriteLine($"Decrypted: {decrypted}");

注意事项:

  • 使用公钥加密,私钥解密。
  • 加密/解密时对填充方式(padding)进行匹配,比如 RSAEncryptionPadding.OaepSHA256
  • RSA 更适合加密小数据,如对称密钥或少量字符串。

结合对称与非对称 —— 推荐的混合加密模式

在实际应用中,为了兼顾性能与安全,推荐采用混合加密(hybrid encryption)模式:

  • 使用对称加密(AES)对字符串或大块数据进行加密 —— 高效。
  • 使用非对称加密(RSA)对 AES 的 Key + IV 进行加密 —— 安全。
  • 接收方先用 RSA 私钥解密出 AES Key + IV,再用它们解密数据。

这种方式兼具对称加密的高吞吐与非对称加密的密钥交换/安全性,非常适合客户端-服务器通信、跨系统传输敏感数据等场景。许多教程和官方文档都推荐这种组合模式。

总结与建议

  • 如果只是对字符串或数据进行本地/同系统加密/解密,使用 AES(对称加密)就足够,效率高、使用简单。
  • 如果存在跨系统/跨网络传输(需要安全地交换密钥、数据传输不被窃听)的需求,推荐用 RSA + AES 的混合加密方式。
  • 切记妥善管理密钥/IV:对称密钥要保密,非对称私钥更要严格保护。
评论