You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# .NET Framework下AES-gcm 128加解密实现相关问题咨询

Bouncy Castle 完全支持 AES-GCM 128 位加解密,以下是完整的实现步骤:

1. 引入Bouncy Castle库到.NET Framework项目
  • 右键你的项目 → 选择「管理NuGet程序包」
  • 搜索 BouncyCastle,找到官方发布的同名包(作者为Legion of the Bouncy Castle Inc.),点击安装即可完成引入
2. 完整AES-GCM 128加解密实现代码

首先引入需要的命名空间:

using System;
using System.Text;
using System.Security.Cryptography;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Modes;
using Org.BouncyCastle.Crypto.Parameters;

完整可运行的加解密代码和测试示例:

// 加密返回结果结构,包含解密需要的所有参数
public struct AesGcmEncryptResult
{
    public byte[] Nonce; // 12字节随机数,解密必须和加密时一致
    public byte[] CipherText; // 加密后的密文
    public byte[] Tag; // 16字节认证标签,用于校验数据完整性
}

/// <summary>
/// AES-GCM 128位加密方法
/// </summary>
/// <param name="key">16字节(128位)加密密钥</param>
/// <param name="plainText">待加密明文</param>
/// <param name="associatedData">可选关联数据,解密时需要传入完全相同的值</param>
public static AesGcmEncryptResult AesGcmEncrypt(byte[] key, string plainText, byte[] associatedData = null)
{
    if (key.Length != 16)
        throw new ArgumentException("AES-GCM 128位密钥长度必须为16字节");
    
    // GCM算法推荐使用12字节的Nonce
    byte[] nonce = new byte[12];
    // 生产环境请使用密码学安全的随机数生成器,不要用Random类
    using (var rng = new RNGCryptoServiceProvider())
    {
        rng.GetBytes(nonce);
    }

    byte[] plainBytes = Encoding.UTF8.GetBytes(plainText);
    GcmBlockCipher gcmCipher = new GcmBlockCipher(new AesEngine());
    AeadParameters parameters = new AeadParameters(new KeyParameter(key), 128, nonce, associatedData);
    gcmCipher.Init(true, parameters);

    byte[] cipherTextWithTag = new byte[gcmCipher.GetOutputSize(plainBytes.Length)];
    int processLen = gcmCipher.ProcessBytes(plainBytes, 0, plainBytes.Length, cipherTextWithTag, 0);
    gcmCipher.DoFinal(cipherTextWithTag, processLen);

    // 拆分密文和认证标签,Tag默认占结果的最后16字节
    byte[] cipherText = new byte[cipherTextWithTag.Length - 16];
    byte[] tag = new byte[16];
    Array.Copy(cipherTextWithTag, 0, cipherText, 0, cipherText.Length);
    Array.Copy(cipherTextWithTag, cipherText.Length, tag, 0, 16);

    return new AesGcmEncryptResult
    {
        Nonce = nonce,
        CipherText = cipherText,
        Tag = tag
    };
}

/// <summary>
/// AES-GCM 128位解密方法
/// </summary>
/// <param name="key">和加密时完全一致的16字节密钥</param>
/// <param name="nonce">加密返回的12字节Nonce</param>
/// <param name="cipherText">加密返回的密文</param>
/// <param name="tag">加密返回的16字节认证标签</param>
/// <param name="associatedData">和加密时完全一致的关联数据,无则传null</param>
public static string AesGcmDecrypt(byte[] key, byte[] nonce, byte[] cipherText, byte[] tag, byte[] associatedData = null)
{
    if (key.Length != 16)
        throw new ArgumentException("AES-GCM 128位密钥长度必须为16字节");
    if (nonce.Length != 12)
        throw new ArgumentException("Nonce长度必须为12字节");
    if (tag.Length != 16)
        throw new ArgumentException("认证标签长度必须为16字节");

    // 合并密文和标签用于解密校验
    byte[] cipherTextWithTag = new byte[cipherText.Length + tag.Length];
    Array.Copy(cipherText, 0, cipherTextWithTag, 0, cipherText.Length);
    Array.Copy(tag, 0, cipherTextWithTag, cipherText.Length, tag.Length);

    GcmBlockCipher gcmCipher = new GcmBlockCipher(new AesEngine());
    AeadParameters parameters = new AeadParameters(new KeyParameter(key), 128, nonce, associatedData);
    gcmCipher.Init(false, parameters);

    byte[] plainBytes = new byte[gcmCipher.GetOutputSize(cipherTextWithTag.Length)];
    int processLen = gcmCipher.ProcessBytes(cipherTextWithTag, 0, cipherTextWithTag.Length, plainBytes, 0);
    gcmCipher.DoFinal(plainBytes, processLen);

    return Encoding.UTF8.GetString(plainBytes);
}

// 测试调用示例
public void TestAesGcm()
{
    // 128位密钥,实际使用请从安全存储获取,不要硬编码
    byte[] aesKey = Encoding.UTF8.GetBytes("your16bytekey1234");
    string plainText = "待加密的测试内容";

    // 加密
    var encryptResult = AesGcmEncrypt(aesKey, plainText);
    Console.WriteLine($"密文Base64:{Convert.ToBase64String(encryptResult.CipherText)}");
    Console.WriteLine($"Nonce Base64:{Convert.ToBase64String(encryptResult.Nonce)}");
    Console.WriteLine($"Tag Base64:{Convert.ToBase64String(encryptResult.Tag)}");

    // 解密
    string decryptText = AesGcmDecrypt(aesKey, encryptResult.Nonce, encryptResult.CipherText, encryptResult.Tag);
    Console.WriteLine($"解密结果:{decryptText}");
}
3. 注意事项
  • 不要直接用用户输入的明文密码作为密钥,实际生产建议通过PBKDF2等密钥派生算法生成符合长度要求的安全密钥
  • 每次加密必须重新生成Nonce,相同密钥+Nonce组合重复使用会导致严重安全漏洞
  • 加密时如果传入了关联数据,解密时必须传入完全相同的值,否则会校验失败抛出异常
  • 密钥、Nonce、Tag三个参数解密时必须和加密时完全一致,任何一位改动都会导致解密失败

内容的提问来源于stack exchange,提问作者Kom Pe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 02:54:03