在C#中实现带认证的现代对称加密,推荐使用AES-GCM算法。它属于AEAD类算法,在加密的同时生成认证标签,解密时会自动校验数据完整性,防止密文被篡改。从.NET Core 3.0开始,System.Security.Cryptography命名空间已原生支持AesGcm类。

一、AES-GCM核心概念
AES-GCM需要三个关键输入:密钥(Key)、随机数(Nonce)和关联数据(AAD)。输出包括密文(Ciphertext)和认证标签(Tag)。解密时必须提供相同的Key、Nonce、AAD和Tag,否则会抛异常。
- Key:建议128或256位,使用密码学安全随机源生成
- Nonce:12字节最佳,不可重复使用同一Key下的Nonce
- Tag:通常为16字节,用于完整性验证
二、加密示例
下面代码展示如何生成密钥与Nonce,并对明文进行加密,输出密文和标签。
using System;
using System.Security.Cryptography;
using System.Text;
class AesGcmDemo
{
static void Main()
{
// 生成256位密钥
byte[] key = new byte[32];
using (var rng = RandomNumberGenerator.Create())
{
rng.GetBytes(key);
}
// 12字节Nonce
byte[] nonce = new byte[12];
using (var rng = RandomNumberGenerator.Create())
{
rng.GetBytes(nonce);
}
string plainText = "敏感数据内容";
byte[] plainBytes = Encoding.UTF8.GetBytes(plainText);
byte[] cipherBytes = new byte[plainBytes.Length];
byte[] tag = new byte[16];
using (var aesGcm = new AesGcm(key))
{
aesGcm.Encrypt(nonce, plainBytes, cipherBytes, tag);
}
Console.WriteLine("密文: " + Convert.ToBase64String(cipherBytes));
Console.WriteLine("标签: " + Convert.ToBase64String(tag));
}
}
三、解密与认证
解密时若密文或标签被篡改,AesGcm会抛出CryptographicException,从而保证数据可信。
using System;
using System.Security.Cryptography;
using System.Text;
class AesGcmDecrypt
{
static void Main()
{
byte[] key = /* 之前生成的密钥 */;
byte[] nonce = /* 之前生成的nonce */;
byte[] cipherBytes = /* 接收的密文 */;
byte[] tag = /* 接收的标签 */;
byte[] decrypted = new byte[cipherBytes.Length];
using (var aesGcm = new AesGcm(key))
{
// 如果数据被篡改,这里会抛出异常
aesGcm.Decrypt(nonce, cipherBytes, tag, decrypted);
}
string result = Encoding.UTF8.GetString(decrypted);
Console.WriteLine("解密结果: " + result);
}
}
四、使用注意事项
1. Nonce管理
同一个密钥下,Nonce绝不能重复。可将Nonce随密文一起存储或传输,它不需要保密。
2. 异常处理
解密失败时应统一返回认证错误,避免向调用方暴露具体失败原因。
3. 关联数据
如果需要在加密时绑定上下文信息(如用户ID),可传入AAD参数,解密时需提供相同AAD。
| 参数 | 是否保密 | 说明 |
|---|---|---|
| Key | 是 | 必须安全保存 |
| Nonce | 否 | 可公开但不可重用 |
| Tag | 否 | 用于校验完整性 |
五、小结
使用C#的AesGcm类可以快速实现带认证的对称加密,比传统AES-CBC加HMAC更简洁安全。实际项目中应重点做好密钥保护和Nonce唯一性控制。