110 lines
3.9 KiB
C#
Raw Normal View History

2024-10-22 09:17:28 +08:00
#if WEIXINMINIGAME && TUANJIE_2022_3_OR_NEWER
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
using AOT;
using UnityEditor;
using UnityEngine;
namespace WeChatWASM
{
public class WebAES
{
public static byte[] EncryptedBytes;
public static byte[] DecryptedBytes;
public static bool initialized;
public static System.IntPtr keyPtr, ivPtr;
public delegate void AesCallback(int enc, System.IntPtr resPtr, int resSize);
[DllImport("__Internal")]
public static extern void WebAesInitialize(
int mode,
System.IntPtr keyPtr, int keySize,
System.IntPtr ivPtr, int ivSize,
AesCallback encCallback, AesCallback decCallback,
int counter = 0, int segmentSize = 0);
[DllImport("__Internal")]
public static extern void WebAesFinalize();
[DllImport("__Internal")]
public static extern void WebAesEncrypt(System.IntPtr plainBytesPtr, int size, int needPad);
[DllImport("__Internal")]
public static extern void WebAesDecrypt(System.IntPtr encryptedBytesPtr, int size, int needStrip);
// TODO: consider passing a unique id so that we can initialize multiple instances.
public static void Initialize(System.Security.Cryptography.CipherMode mode, byte[] key,
byte[] iv, int counter = 0, int segmentSize = 0)
{
if (initialized)
{
Debug.Log("Already initialized! Please call Finalize() before initialize again.");
return;
}
if (mode == CipherMode.CTS)
{
Debug.LogError("CTS not supported!");
return;
}
int keySize = key.Length;
keyPtr = Marshal.AllocHGlobal(keySize);
Marshal.Copy(key, 0, keyPtr, keySize);
int ivSize = iv.Length;
ivPtr = Marshal.AllocHGlobal(ivSize);
Marshal.Copy(iv, 0, ivPtr, ivSize);
WebAesInitialize(
(int)mode,
keyPtr, keySize, ivPtr, ivSize,
OnAecCrypto, OnAecCrypto,
counter, segmentSize);
initialized = true;
}
[MonoPInvokeCallback(typeof(AesCallback))]
public static void OnAecCrypto(int enc, System.IntPtr resPtr, int resSize)
{
byte[] res = new byte[resSize];
Marshal.Copy(resPtr, res, 0, resSize);
if (enc == 1)
{
EncryptedBytes = res;
}
else
{
DecryptedBytes = res;
}
}
// TODO: consider passing a unique id so we can destroy by instance.
public static void Finalize()
{
EncryptedBytes = null;
DecryptedBytes = null;
Marshal.FreeHGlobal(keyPtr);
Marshal.FreeHGlobal(ivPtr);
initialized = false;
WebAesFinalize();
}
// Use UTF-8 as it is used as default format for StreamReader
public static byte[] Encode(string plainStr, bool needPad = true)
{
var bytes = Encoding.UTF8.GetBytes(plainStr);
var bytesPtr = Marshal.AllocHGlobal(bytes.Length);
Marshal.Copy(bytes, 0, bytesPtr, bytes.Length);
WebAesEncrypt(bytesPtr, bytes.Length, needPad ? 1 : 0);
Marshal.FreeHGlobal(bytesPtr);
return EncryptedBytes;
}
public static string Decode(byte[] bytes, bool needStrip = true)
{
var bytesPtr = Marshal.AllocHGlobal(bytes.Length);
Marshal.Copy(bytes, 0, bytesPtr, bytes.Length);
WebAesDecrypt(bytesPtr, bytes.Length, needStrip ? 1 : 0);
Marshal.FreeHGlobal(bytesPtr);
return Encoding.UTF8.GetString(DecryptedBytes);
}
}
}
#endif