Unity接入中宣部防沉迷实名认证之AES-128/GCM + BASE64加密(二)
背景
在上一篇 Unity接入中宣部防沉迷实名认证之AES-128/GCM + BASE64加密(一) 中,使用的是Chilkat插件,但是由于购买太昂贵,所以决定弃用,有了这一篇文章。
基于 The Legion of the Bouncy Castle 生成C#库
因为最终要在Unity中使用,所以我这里新建一个可用于Android和iOS的
.NET Standard 2.0
库,然后安装BouncyCastle这个插件。
库中只有一个脚本
AesGcm.cs
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities.Encoders;
using System;
using System.Text;
namespace AesGcmCrypt
public class AesGcm
private const string ALGORITHM_NAME = "AES";
private const int NONCE_LEN = 12;
private const int ALGORITHM_KEY_SIZE = 16;
private const int TAG_LEN = 16;
private const int PBKDF2_ITERATIONS = 32767;
public static string Encrypt(string plainText, string secretKey)
var cipherText = string.Empty;
byte[] K = Hex.Decode(secretKey);
byte[] P = Encoding.UTF8.GetBytes(plainText);
byte[] N = new byte[NONCE_LEN];
Random random = new Random();
random.NextBytes(N);
KeyParameter key = ParameterUtilities.CreateKeyParameter(ALGORITHM_NAME, K);
IBufferedCipher inCipher = CipherUtilities.GetCipher("AES/GCM/NoPadding");
inCipher.Init(true, new ParametersWithIV(key, N));
byte[] enc = inCipher.DoFinal(P);
byte[] data = new byte[N.Length + enc.Length];
Array.ConstrainedCopy(N, 0, data, 0, N.Length);
Array.ConstrainedCopy(enc, 0, data, N.Length, enc.Length);
cipherText = Convert.ToBase64String(data);
return cipherText;
public static string Decrypt(string cipherText, string secretKey)
byte[] data = Convert.FromBase64String(cipherText);
byte[] iv = new byte[NONCE_LEN];
//byte[] tag = new byte[TAG_LEN];
byte[] cipherData = new byte[data.Length /*- tag.Length*/ - iv.Length];
//Array.Copy(data, data.Length-tag.Length, tag, 0, tag.Length);
Array.Copy(data, 0, iv, 0, iv.Length);
Array.Copy(data, iv.Length, cipherData, 0, cipherData.Length);
byte[] keyData = Hex.Decode(secretKey);
KeyParameter key = ParameterUtilities.CreateKeyParameter(ALGORITHM_NAME, keyData);
IBufferedCipher outCipher = CipherUtilities.GetCipher("AES/GCM/NoPadding");
outCipher.Init(false, new ParametersWithIV(key, iv));
byte[] dec = outCipher.DoFinal(cipherData);
var plainText = Encoding.UTF8.GetString(dec);
return plainText;
using AesGcmCrypt;
using System;
namespace Test
class Program
static void Main(string[] args)
Console.WriteLine("Hello World!");
string secretKey = "2836e95fcd10e04b0069bb1ee659955b";
string jsondata = "{\"ai\":\"test-accountId\",\"name\":\"用户姓名\",\"idNum\":\"371321199012310912\"}";
var data = "CqT/33f3jyoiYqT8MtxEFk3x2rlfhmgzhxpHqWosSj4d3hq2EbrtVyx2aLj565ZQNTcPrcDipnvpq/D/vQDaLKW70O83Q42zvR0//OfnYLcIjTPMnqa+SOhsjQrSdu66ySSORCAo";
var data2 = AesGcm.Decrypt(data, secretKey);
Console.WriteLine("测试用例解密:" + data2);
data = AesGcm.Encrypt(jsondata, secretKey);
Console.WriteLine("自行加密后:" + data);
//data = "CqT/33f3jyoiYqT8MtxEFk3x2rlfhmgzhxpHqWosSj4d3hq2EbrtVyx2aLj565ZQNTcPrcDipnvpq/D/vQDaLKW70O83Q42zvR0//OfnYLcIjTPMnqa+SOhsjQrSdu66ySSORCAo";
data2 = AesGcm.Decrypt(data, secretKey);
Console.WriteLine("自行解密后:" + data2);
Console.ReadLine();
输出结果: