杂项

当前位置:首页>技术博客>杂项
全部 15 TFrame框架 2 游戏渲染 0 编辑器扩展 0 性能优化 3 SDK 4 数据结构和算法 1 杂项 5

Unity接入中宣部防沉迷实名认证之AES-128/GCM + BASE64加密(二)

时间:2021-06-11   访问量:1570

背景

在上一篇[Unity接入中宣部防沉迷实名认证之AES-128/GCM + BASE64加密(一)](https://www.jianshu.com/p/2f9d1e36ff49)中,使用的是Chilkat插件,但是由于购买太昂贵,所以决定弃用,有了这一篇文章。


基于[The Legion of the Bouncy Castle](https://www.bouncycastle.org/csharp/index.html)生成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();
        }
    }
}


输出结果:


Chilkat和BouncyCastle比较

- BouncyCastle免费开源库;Chilkat需要付费解锁API,而且价格很贵。

- Chilkat在加解密的时候,都能获取到TAG,格式是`IV + 真正密文 + TAG`;而BouncyCastle的格式是:`IV + 真正密文`


上一篇:Unity接入中宣部防沉迷实名认证之AES-128/GCM + BASE64加密(一)

下一篇:Unity发送GET和POST请求

发表评论:

评论记录:

未查询到任何数据!