C#AES加密

一、AES 加密概念

  • 定义 :AES(Advanced Encryption Standard,高级加密标准)是一种对称加密算法,由美国国家标准与技术研究院(NIST)于 2001 年发布,用于替代之前的 DES(数据加密标准)。它是一种分组密码,以 128 位(16 字节)为分组长度,支持 128 位、192 位和 256 位的密钥长度,分别为 AES - 128、AES - 192 和 AES - 256,其中 AES - 128 应用最为广泛。

  • 应用场景 :适用于对数据安全性和加密效率要求较高的场景,如文件加密、网络数据传输加密、磁盘加密、移动存储设备加密、云存储数据加密以及企业内部敏感信息加密等。

二、AES 加密原理

  • 分组加密 :AES 将明文按 128 位(16 字节)的分组长度进行分割,每个分组独立进行加密操作,生成相应的 128 位密文分组。对于不足 16 字节的数据,需要进行填充(Padding)操作,使其达到 16 字节的倍数。

  • 密钥扩展 :根据用户提供的主密钥(如 128 位、192 位或 256 位),通过特定的密钥扩展算法生成一系列轮密钥(Round Key)。这些轮密钥在加密和解密过程中逐轮使用,用于混合和混淆数据,增强加密的安全性。

  • 加密轮数 :AES - 128 需要进行 10 轮加密操作,AES - 192 需要 12 轮,AES - 256 需要 14 轮。每轮加密操作都包括字节替代(SubBytes)、行移位(ShiftRows)、列混合(MixColumns)和轮密钥加(AddRoundKey)四个步骤,除了最后一轮不进行列混合操作。

  1. 字节替代(SubBytes) :将每个字节替换为 S - 框(Substitution Box)中对应的字节。S - 框是一种非线性替换表,其设计基于有限域上的乘法逆元和仿射变换,目的是增加加密的复杂性和安全性,使明文和密文之间的关系更加混乱。

  2. 行移位(ShiftRows) :对状态矩阵(由分组数据构成的 4×4 字节矩阵)的每一行进行循环移位操作。具体来说,第 0 行不移位,第 1 行循环左移一个字节,第 2 行循环左移两个字节,第 3 行循环左移三个字节。这样可以打破分组数据的原始排列顺序,增加数据的扩散性,使明文的相邻字节在密文中分散到不同的位置,提高加密的抗攻击能力。

  3. 列混合(MixColumns) :将状态矩阵的每一列视为有限域上的多项式,并与一个固定的多项式进行乘法运算,然后取模。这一操作可以进一步混合各列的数据,使一个字节的改变影响到整个列的数据,从而增强加密的扩散性,使密文对明文的微小变化更加敏感。

  4. 轮密钥加(AddRoundKey) :将当前状态矩阵与轮密钥进行按位异或(XOR)操作。轮密钥是通过密钥扩展算法生成的,与明文数据进行异或操作可以引入密钥的随机性,使密文与明文之间的关系更加复杂,同时确保只有使用正确的密钥才能解密密文。

三、AES 加密用法(以 C# 为例)

  • 加密文件示例

    cs 复制代码
    using System;
    using System.IO;
    using System.Security.Cryptography;
    
    public class AESFileEncryption
    {
        public static void Main()
        {
            string sourceFilePath = @"C:\input.txt"; // 明文文件路径
            string destinationFilePath = @"C:\encrypted.enc"; // 加密后的文件保存路径
            string password = "MySecurePassword123"; // 加密密码
            string salt = "MySaltValue"; // 盐值
    
            try
            {
                using (Aes aes = Aes.Create())
                {
                    // 根据密码和盐值生成密钥和 IV
                    Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(password, Encoding.UTF8.GetBytes(salt));
                    aes.Key = pdb.GetBytes(aes.KeySize / 8);
                    aes.IV = pdb.GetBytes(aes.BlockSize / 8);
    
                    // 创建加密器
                    ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
    
                    // 使用加密流加密文件
                    using (FileStream inputStream = new FileStream(sourceFilePath, FileMode.Open, FileAccess.Read))
                    using (FileStream outputStream = new FileStream(destinationFilePath, FileMode.Create, FileAccess.Write))
                    using (CryptoStream cryptoStream = new CryptoStream(outputStream, encryptor, CryptoStreamMode.Write))
                    {
                        byte[] buffer = new byte[1024];
                        int bytesRead;
                        while ((bytesRead = inputStream.Read(buffer, 0, buffer.Length)) > 0)
                        {
                            cryptoStream.Write(buffer, 0, bytesRead);
                        }
                    }
                    Console.WriteLine("文件加密完成!");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("文件加密过程中发生错误: " + ex.Message);
            }
        }
    }
  • 解密文件示例

    cs 复制代码
    using System;
    using System.IO;
    using System.Security.Cryptography;
    
    public class AESFileDecryption
    {
        public static void Main()
        {
            string sourceFilePath = @"C:\encrypted.enc"; // 密文文件路径
            string destinationFilePath = @"C:\decrypted.txt"; // 解密后的文件保存路径
            string password = "MySecurePassword123"; // 解密密码(需与加密时的密码相同)
            string salt = "MySaltValue"; // 盐值(需与加密时的盐值相同)
    
            try
            {
                using (Aes aes = Aes.Create())
                {
                    // 根据密码和盐值生成密钥和 IV
                    Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(password, Encoding.UTF8.GetBytes(salt));
                    aes.Key = pdb.GetBytes(aes.KeySize / 8);
                    aes.IV = pdb.GetBytes(aes.BlockSize / 8);
    
                    // 创建解密器
                    ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
    
                    // 使用解密流解密文件
                    using (FileStream inputStream = new FileStream(sourceFilePath, FileMode.Open, FileAccess.Read))
                    using (FileStream outputStream = new FileStream(destinationFilePath, FileMode.Create, FileAccess.Write))
                    using (CryptoStream cryptoStream = new CryptoStream(inputStream, decryptor, CryptoStreamMode.Read))
                    {
                        byte[] buffer = new byte[1024];
                        int bytesRead;
                        while ((bytesRead = cryptoStream.Read(buffer, 0, buffer.Length)) > 0)
                        {
                            outputStream.Write(buffer, 0, bytesRead);
                        }
                    }
                    Console.WriteLine("文件解密完成!");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("文件解密过程中发生错误: " + ex.Message);
            }
        }
    }
  • 加密字符串示例

    cs 复制代码
    using System;
    using System.Security.Cryptography;
    using System.Text;
    
    public class AESEncryptionExample
    {
        public static void Main()
        {
            string plainText = "这是一段需要加密的文本"; // 明文
            string password = "MySecurePassword123"; // 密码
            string salt = "MySaltValue"; // 盐值
    
            try
            {
                using (Aes aes = Aes.Create())
                {
                    // 根据密码和盐值生成密钥和 IV
                    Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(password, Encoding.UTF8.GetBytes(salt));
                    aes.Key = pdb.GetBytes(aes.KeySize / 8);
                    aes.IV = pdb.GetBytes(aes.BlockSize / 8);
    
                    // 创建加密器
                    ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
    
                    // 加密字符串
                    byte[] plainBytes = Encoding.UTF8.GetBytes(plainText);
                    using (MemoryStream ms = new MemoryStream())
                    {
                        using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
                        {
                            cs.Write(plainBytes, 0, plainBytes.Length);
                        }
                        byte[] encryptedBytes = ms.ToArray();
                        string encryptedText = Convert.ToBase64String(encryptedBytes);
                        Console.WriteLine("加密后的文本: " + encryptedText);
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("加密过程中发生错误: " + ex.Message);
            }
        }
    }
  • 解密字符串示例

    cs 复制代码
    using System;
    using System.Security.Cryptography;
    using System.Text;
    
    public class AESDecryptionExample
    {
        public static void Main()
        {
            string encryptedText = "加密后的文本"; // 密文(Base64 编码)
            string password = "MySecurePassword123"; // 密码
            string salt = "MySaltValue"; // 盐值
    
            try
            {
                using (Aes aes = Aes.Create())
                {
                    // 根据密码和盐值生成密钥和 IV
                    Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(password, Encoding.UTF8.GetBytes(salt));
                    aes.Key = pdb.GetBytes(aes.KeySize / 8);
                    aes.IV = pdb.GetBytes(aes.BlockSize / 8);
    
                    // 创建解密器
                    ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
    
                    // 解密字符串
                    byte[] encryptedBytes = Convert.FromBase64String(encryptedText);
                    using (MemoryStream ms = new MemoryStream(encryptedBytes))
                    {
                        using (CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
                        {
                            using (StreamReader sr = new StreamReader(cs))
                            {
                                string decryptedText = sr.ReadToEnd();
                                Console.WriteLine("解密后的文本: " + decryptedText);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("解密过程中发生错误: " + ex.Message);
            }
        }
    }

    四、AES 加密的优缺点

优点

  • 安全性高 :AES 经过了广泛的安全分析和测试,目前没有被公开破解的有效方法。其加密强度随着密钥长度的增加而显著提高,如 AES - 256 的密钥空间极大,使得暴力破解几乎不可能实现。

  • 加密效率高 :AES 算法在现代计算机硬件上具有较高的加密和解密速度,能够快速处理大量数据,适用于对实时性要求较高的应用场景,如网络数据传输加密和视频流加密等。

  • 灵活性强 :支持多种密钥长度(128 位、192 位和 256 位),用户可以根据实际安全需求和性能要求选择合适的密钥长度。同时,AES 还可以与其他加密技术(如哈希算法、数字签名等)结合使用,构建更强大的安全体系。

  • 广泛应用 :由于其优异的性能和安全性,AES 已经成为全球广泛使用的加密标准之一,得到了众多软件和硬件厂商的支持。在操作系统、数据库管理系统、网络设备、加密软件等领域都有广泛的应用,用户可以方便地找到各种实现和工具来使用 AES 加密。

缺点

  • 密钥管理复杂 :作为对称加密算法,加密和解密使用相同的密钥,因此密钥的分发和管理是一个关键问题。如果密钥在传输或存储过程中泄露,攻击者就可以轻易地解密密文,获取敏感信息。在分布式系统或多用户环境中,密钥的共享和更新需要采用安全的密钥交换协议和密钥管理系统,增加了系统的复杂性和管理成本。

  • 不适合大规模密钥分发 :在需要与大量用户进行加密通信的场景下,对称加密算法的密钥分发问题会变得更加突出。例如,如果有 n 个用户,每个用户之间都需要共享一个唯一的密钥,则总共需要 n(n-1)/2 个密钥。当 n 很大时,密钥的数量会呈平方级增长,给密钥管理带来巨大的挑战。

  • 无法实现数字签名 :对称加密算法只能保证数据的机密性,无法像非对称加密算法那样实现数字签名功能,用于验证数据的完整性和发送者的身份。因此,在需要同时满足数据加密和身份认证的场景下,通常需要将对称加密算法与非对称加密算法结合使用。

相关推荐
一心同学14 分钟前
Hermes架构拆解之Tool执行安全机制
安全·架构·agent·hermes
天天代码码天天17 分钟前
屏幕翻拍满是彩色条纹?用 C# + Vulkan 做了一个去摩尔纹工具,支持单图与文件夹批量
c#·去摩尔纹
白帽攻防录20 分钟前
SRC 挖洞:QUIC 协议栈双 RCE,HTTP/3 的新攻击面怎么挖
网络·网络协议·http·网络安全·http/3
墨云安全23 分钟前
AI 漏洞挖掘平台怎么评估?2026 年技术架构与选型要点
网络·人工智能·网络安全·架构·渗透测试
2501_9307077830 分钟前
使用C#代码在 Word 文档中添加、插入或删除页面
开发语言·c#·word
小草cys35 分钟前
ubuntu忘记密码怎么重置
安全·ubuntu·密码重置
Ikalus198835 分钟前
对端说「1 秒后再来」,Alertmanager 判定「永远不要重试」:这个错认了 6 年 9 个月
安全·架构
红姐跨境书41 分钟前
TikTok 爬虫实战指南:避开 TikTok 反爬机制的 7个坑
网络
隐擎fox1 小时前
Linux eBPF 与 XDP 高性能网络出口架构:动态连接追踪、丢包诊断与住宅网关 QoS 调优实战
linux·网络·网络协议·tcp/ip·架构
Multipath7121 小时前
多链路聚合设备:助力智慧农业发展的网络基石——让农田网络不断连,让智能设备不失控
网络·网络协议·5g·udp·无人机