1. AES加密技术概述
AES(Advanced Encryption Standard)作为目前最广泛使用的对称加密算法,在数据安全领域占据着核心地位。2001年由美国国家标准与技术研究院(NIST)正式确立为标准,取代了原有的DES加密算法。其核心优势在于高效的安全性能与适中的计算资源消耗,特别适合现代应用场景中的数据保护需求。
在.NET生态中,System.Security.Cryptography命名空间提供了完整的AES实现,支持128位、192位和256位三种密钥长度。实际开发中最常用的是256位版本,因其在安全性与性能之间取得了较好的平衡。值得注意的是,AES算法本身只是加密方案的核心,实际应用中还需要配合适当的加密模式(如CBC、ECB)和填充方案(如PKCS7)才能构成完整的加密解决方案。
2. 加密基础配置
2.1 密钥与初始向量生成
安全实践中最关键的是密钥管理。以下是推荐的做法:
csharp复制using System.Security.Cryptography;
byte[] GenerateRandomBytes(int length)
{
using var rng = RandomNumberGenerator.Create();
byte[] bytes = new byte[length];
rng.GetBytes(bytes);
return bytes;
}
// 生成256位(32字节)密钥
var key = GenerateRandomBytes(32);
// 生成128位(16字节)初始向量
var iv = GenerateRandomBytes(16);
重要提示:绝对不要使用固定密钥或简单字符串转换的密钥。每次加密都应使用新的随机IV,但密钥可以重复使用(需安全存储)。
2.2 加密模式选择
CBC(Cipher Block Chaining)是最推荐的加密模式,相比ECB更安全:
csharp复制var aes = Aes.Create();
aes.Mode = CipherMode.CBC; // 默认即为CBC,但显式设置更明确
aes.Padding = PaddingMode.PKCS7;
ECB模式由于存在安全隐患,除非有特殊兼容性需求,否则不应在生产环境中使用。GCM模式则提供额外的完整性验证,适合更高安全要求的场景。
3. 完整加密实现
3.1 加密流程分步实现
csharp复制string EncryptString(string plainText, byte[] key, byte[] iv)
{
using var aes = Aes.Create();
aes.Key = key;
aes.IV = iv;
using var encryptor = aes.CreateEncryptor();
using var ms = new MemoryStream();
using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
using (var sw = new StreamWriter(cs))
{
sw.Write(plainText);
}
return Convert.ToBase64String(ms.ToArray());
}
3.2 解密流程分步实现
csharp复制string DecryptString(string cipherText, byte[] key, byte[] iv)
{
byte[] buffer = Convert.FromBase64String(cipherText);
using var aes = Aes.Create();
aes.Key = key;
aes.IV = iv;
using var decryptor = aes.CreateDecryptor();
using var ms = new MemoryStream(buffer);
using var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read);
using var sr = new StreamReader(cs);
return sr.ReadToEnd();
}
4. 生产环境最佳实践
4.1 密钥安全管理方案
实际项目中推荐采用分层密钥管理策略:
- 主密钥使用硬件安全模块(HSM)或云密钥管理服务(如Azure Key Vault)
- 数据加密密钥(DEK)由主密钥加密后存储
- 每次加密使用不同的IV与相同的DEK
csharp复制// 与Azure Key Vault集成示例
public async Task<byte[]> GetEncryptionKeyAsync()
{
var client = new SecretClient(
new Uri("https://your-vault.vault.azure.net/"),
new DefaultAzureCredential());
KeyVaultSecret secret = await client.GetSecretAsync("DataEncryptionKey");
return Convert.FromBase64String(secret.Value);
}
4.2 性能优化技巧
处理大文件时应采用流式处理:
csharp复制void EncryptFile(string inputPath, string outputPath, byte[] key, byte[] iv)
{
using var aes = Aes.Create();
aes.Key = key;
aes.IV = iv;
using var inputStream = File.OpenRead(inputPath);
using var outputStream = File.Create(outputPath);
using var cryptoStream = new CryptoStream(
outputStream,
aes.CreateEncryptor(),
CryptoStreamMode.Write);
inputStream.CopyTo(cryptoStream);
}
5. 常见问题排查
5.1 典型异常处理
| 异常类型 | 可能原因 | 解决方案 |
|---|---|---|
| CryptographicException | 密钥/IV长度不符 | 检查密钥是否为32字节,IV为16字节 |
| FormatException | Base64字符串格式错误 | 验证密文是否完整且未篡改 |
| ArgumentException | 使用了错误的填充模式 | 确保加密解密使用相同的PaddingMode |
5.2 跨平台兼容性
当需要与Java等其他平台交互时,需特别注意:
- 确认双方使用相同的密钥派生算法
- 统一使用UTF-8编码处理文本
- 验证双方的Base64编码标准是否一致
java复制// Java端对应解密示例
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "AES"),
new IvParameterSpec(iv));
6. 安全增强方案
6.1 认证加密实现
GCM模式提供加密和完整性验证:
csharp复制string EncryptWithGcm(string plainText, byte[] key)
{
using var aes = new AesGcm(key);
byte[] nonce = new byte[AesGcm.NonceByteSizes.MaxSize];
RandomNumberGenerator.Fill(nonce);
byte[] plainBytes = Encoding.UTF8.GetBytes(plainText);
byte[] cipherText = new byte[plainBytes.Length];
byte[] tag = new byte[AesGcm.TagByteSizes.MaxSize];
aes.Encrypt(nonce, plainBytes, cipherText, tag);
// 组合nonce + tag + cipherText用于传输
return Convert.ToBase64String(nonce.Concat(tag).Concat(cipherText).ToArray());
}
6.2 密钥轮换策略
建议的安全实践包括:
- 每90天轮换主密钥
- 使用密钥版本控制
- 新数据用新密钥加密
- 旧数据在访问时迁移到新密钥
csharp复制// 密钥版本控制示例
public class EncryptedData
{
public int KeyVersion { get; set; }
public byte[] IV { get; set; }
public string CipherText { get; set; }
}