相关文章推荐
忧郁的海龟  ·  JS 实现 ...·  1 月前    · 
直爽的烤红薯  ·  java ...·  1 月前    · 
酒量小的煎饼  ·  python pyside pyqt ...·  11 月前    · 
精彩文章免费看

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();

输出结果: