重构 Encryptor
parent
69e6068dd0
commit
a7db16475a
|
@ -38,7 +38,7 @@ namespace Obfuz.Data
|
||||||
{
|
{
|
||||||
public FieldDef holderDataField;
|
public FieldDef holderDataField;
|
||||||
public FieldDef runtimeValueField;
|
public FieldDef runtimeValueField;
|
||||||
public long encryptionOps;
|
public int encryptionOps;
|
||||||
public uint size;
|
public uint size;
|
||||||
public List<byte> bytes;
|
public List<byte> bytes;
|
||||||
public int salt;
|
public int salt;
|
||||||
|
@ -134,7 +134,7 @@ namespace Obfuz.Data
|
||||||
runtimeValueField = runtimeValueField,
|
runtimeValueField = runtimeValueField,
|
||||||
size = dataHolderType.ClassSize,
|
size = dataHolderType.ClassSize,
|
||||||
bytes = new List<byte>((int)dataHolderType.ClassSize),
|
bytes = new List<byte>((int)dataHolderType.ClassSize),
|
||||||
encryptionOps = _random.NextLong(),
|
encryptionOps = _random.NextInt(),
|
||||||
salt = _random.NextInt(),
|
salt = _random.NextInt(),
|
||||||
};
|
};
|
||||||
_rvaFields.Add(newRvaField);
|
_rvaFields.Add(newRvaField);
|
||||||
|
@ -252,7 +252,7 @@ namespace Obfuz.Data
|
||||||
ins.Add(Instruction.Create(OpCodes.Call, importer.InitializedArrayMethod));
|
ins.Add(Instruction.Create(OpCodes.Call, importer.InitializedArrayMethod));
|
||||||
|
|
||||||
// EncryptionService.DecryptBlock(array, field.encryptionOps, field.salt);
|
// EncryptionService.DecryptBlock(array, field.encryptionOps, field.salt);
|
||||||
ins.Add(Instruction.Create(OpCodes.Ldc_I8, field.encryptionOps));
|
ins.Add(Instruction.CreateLdcI4(field.encryptionOps));
|
||||||
ins.Add(Instruction.Create(OpCodes.Ldc_I4, field.salt));
|
ins.Add(Instruction.Create(OpCodes.Ldc_I4, field.salt));
|
||||||
ins.Add(Instruction.Create(OpCodes.Call, importer.DecryptBlock));
|
ins.Add(Instruction.Create(OpCodes.Call, importer.DecryptBlock));
|
||||||
|
|
||||||
|
|
|
@ -26,9 +26,9 @@ namespace Obfuz.Emit
|
||||||
Assert.IsNotNull(_initializeArray);
|
Assert.IsNotNull(_initializeArray);
|
||||||
|
|
||||||
Type encryptionService = typeof(EncryptionService);
|
Type encryptionService = typeof(EncryptionService);
|
||||||
_encryptBlock = mod.Import(encryptionService.GetMethod("EncryptBlock", new[] { typeof(byte[]), typeof(long), typeof(int) }));
|
_encryptBlock = mod.Import(encryptionService.GetMethod("EncryptBlock", new[] { typeof(byte[]), typeof(int), typeof(int) }));
|
||||||
Assert.IsNotNull(_encryptBlock);
|
Assert.IsNotNull(_encryptBlock);
|
||||||
_decryptBlock = mod.Import(encryptionService.GetMethod("DecryptBlock", new[] { typeof(byte[]), typeof(long), typeof(int) }));
|
_decryptBlock = mod.Import(encryptionService.GetMethod("DecryptBlock", new[] { typeof(byte[]), typeof(int), typeof(int) }));
|
||||||
Assert.IsNotNull(_decryptBlock);
|
Assert.IsNotNull(_decryptBlock);
|
||||||
_encryptInt = mod.Import(encryptionService.GetMethod("Encrypt", new[] { typeof(int), typeof(int), typeof(int) }));
|
_encryptInt = mod.Import(encryptionService.GetMethod("Encrypt", new[] { typeof(int), typeof(int), typeof(int) }));
|
||||||
Assert.IsNotNull(_encryptInt);
|
Assert.IsNotNull(_encryptInt);
|
||||||
|
|
|
@ -1,257 +0,0 @@
|
||||||
using Obfuz.Utils;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq.Expressions;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Text;
|
|
||||||
using Unity.Collections.LowLevel.Unsafe;
|
|
||||||
using UnityEngine.Assertions;
|
|
||||||
using UnityEngine.UIElements;
|
|
||||||
|
|
||||||
namespace Obfuz.Encryption
|
|
||||||
{
|
|
||||||
public class VirtualMachine
|
|
||||||
{
|
|
||||||
public const int SecretKeyLength = 1024;
|
|
||||||
|
|
||||||
public readonly int vmSeed;
|
|
||||||
public readonly EncryptOpCode[] opCodes;
|
|
||||||
|
|
||||||
public VirtualMachine(int vmSeed, EncryptOpCode[] opCodes)
|
|
||||||
{
|
|
||||||
this.vmSeed = vmSeed;
|
|
||||||
this.opCodes = opCodes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface IVirtualMachineCreator
|
|
||||||
{
|
|
||||||
VirtualMachine CreateVirtualMachine(int opCodeCount, int vmSeed);
|
|
||||||
}
|
|
||||||
|
|
||||||
public class RandomVirtualMachineCreator : IVirtualMachineCreator
|
|
||||||
{
|
|
||||||
private readonly int[] _debugSecretKey;
|
|
||||||
|
|
||||||
public RandomVirtualMachineCreator()
|
|
||||||
{
|
|
||||||
_debugSecretKey = new int[VirtualMachine.SecretKeyLength];
|
|
||||||
for (int i = 0; i < _debugSecretKey.Length; i++)
|
|
||||||
{
|
|
||||||
_debugSecretKey[i] = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private IEncryptInstruction CreateRandomInstruction(IRandom random, int secretKeyLength)
|
|
||||||
{
|
|
||||||
switch (random.NextInt(3))
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
return new AddInstruction(random.NextInt(), random.NextInt(secretKeyLength));
|
|
||||||
case 1:
|
|
||||||
return new XorInstruction(random.NextInt(), random.NextInt(secretKeyLength));
|
|
||||||
case 2:
|
|
||||||
return new BitRotateInstruction(random.NextInt(32), random.NextInt(secretKeyLength));
|
|
||||||
default:
|
|
||||||
throw new System.Exception("Invalid instruction type");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private EncryptOpCode CreateEncryptOpCode(ushort code, IRandom r, int opCodeCount)
|
|
||||||
{
|
|
||||||
Assert.IsTrue(code < opCodeCount);
|
|
||||||
var insts = new IEncryptInstruction[opCodeCount];
|
|
||||||
for (int i = 0; i < insts.Length; i++)
|
|
||||||
{
|
|
||||||
IEncryptInstruction inst = CreateRandomInstruction(r, VirtualMachine.SecretKeyLength);
|
|
||||||
Assert.AreEqual(1234, inst.Decrypt(inst.Encrypt(1234, _debugSecretKey, i), _debugSecretKey, i));
|
|
||||||
insts[i] = CreateRandomInstruction(r, opCodeCount);
|
|
||||||
}
|
|
||||||
var function = new EncryptFunction(insts);
|
|
||||||
Assert.AreEqual(1234, function.Decrypt(function.Encrypt(1234, _debugSecretKey, code), _debugSecretKey, code));
|
|
||||||
return new EncryptOpCode(code, function);
|
|
||||||
}
|
|
||||||
|
|
||||||
public VirtualMachine CreateVirtualMachine(int opCodeCount, int vmSeed)
|
|
||||||
{
|
|
||||||
Assert.IsTrue(opCodeCount > 0);
|
|
||||||
Assert.AreEqual(0, opCodeCount ^ (opCodeCount - 1));
|
|
||||||
IRandom r = new RandomWithKey(new byte[] {1,2,3,4,5,6}, vmSeed);
|
|
||||||
var opCodes = new EncryptOpCode[opCodeCount];
|
|
||||||
for (int i = 0; i < opCodes.Length; i++)
|
|
||||||
{
|
|
||||||
opCodes[i] = CreateEncryptOpCode((ushort)i, r, opCodeCount);
|
|
||||||
}
|
|
||||||
return new VirtualMachine(vmSeed, opCodes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class EncryptVirtualMachineSimulator
|
|
||||||
{
|
|
||||||
private readonly EncryptOpCode[] _opCodes;
|
|
||||||
private readonly int[] _secretKey;
|
|
||||||
|
|
||||||
public EncryptVirtualMachineSimulator(EncryptOpCode[] opCodes, int[] secretKey)
|
|
||||||
{
|
|
||||||
_opCodes = opCodes;
|
|
||||||
// should be power of 2
|
|
||||||
Assert.AreEqual(0, opCodes.Length ^ (opCodes.Length - 1));
|
|
||||||
_secretKey = secretKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<ushort> DecodeOps(int ops)
|
|
||||||
{
|
|
||||||
var codes = new List<ushort>();
|
|
||||||
while (ops > 0)
|
|
||||||
{
|
|
||||||
var code = (ushort)(ops % _opCodes.Length);
|
|
||||||
codes.Add(code);
|
|
||||||
ops >>= 16;
|
|
||||||
}
|
|
||||||
return codes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Encrypt(int value, int ops, int salt)
|
|
||||||
{
|
|
||||||
var codes = DecodeOps(ops);
|
|
||||||
foreach (var code in codes)
|
|
||||||
{
|
|
||||||
var opCode = _opCodes[code];
|
|
||||||
value = opCode.Encrypt(value, _secretKey, salt);
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Decrypt(int value, int ops, int salt)
|
|
||||||
{
|
|
||||||
var codes = DecodeOps(ops);
|
|
||||||
for (int i = codes.Count - 1; i >= 0; i--)
|
|
||||||
{
|
|
||||||
var opCode = _opCodes[codes[i]];
|
|
||||||
value = opCode.Decrypt(value, _secretKey, salt);
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long Encrypt(long value, int ops, int salt)
|
|
||||||
{
|
|
||||||
int low = (int)(value & 0xFFFFFFFF);
|
|
||||||
int high = (int)((value >> 32) & 0xFFFFFFFF);
|
|
||||||
var codes = DecodeOps(ops);
|
|
||||||
|
|
||||||
// TODO we should encrypt high with encLow
|
|
||||||
int encLow = Encrypt(low, ops, salt);
|
|
||||||
int encHigh = Encrypt(high, ops, salt);
|
|
||||||
|
|
||||||
return ((long)encHigh << 32) | (long)(uint)(encLow);
|
|
||||||
}
|
|
||||||
|
|
||||||
public long Decrypt(long value, int ops, int salt)
|
|
||||||
{
|
|
||||||
int low = (int)(value & 0xFFFFFFFF);
|
|
||||||
int high = (int)((value >> 32) & 0xFFFFFFFF);
|
|
||||||
var codes = DecodeOps(ops);
|
|
||||||
|
|
||||||
// TODO we should encrypt high with encLow
|
|
||||||
int decLow = Decrypt(low, ops, salt);
|
|
||||||
int decHigh = Decrypt(high, ops, salt);
|
|
||||||
|
|
||||||
return ((long)decHigh << 32) | (long)(uint)(decLow);
|
|
||||||
}
|
|
||||||
|
|
||||||
public float Encrypt(float value, int ops, int salt)
|
|
||||||
{
|
|
||||||
int intValue = UnsafeUtility.As<float, int>(ref value);
|
|
||||||
int encValue = Encrypt(intValue, ops, salt);
|
|
||||||
return UnsafeUtility.As<int, float>(ref encValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
public float Decrypt(float value, int ops, int salt)
|
|
||||||
{
|
|
||||||
int intValue = UnsafeUtility.As<float, int>(ref value);
|
|
||||||
int decValue = Decrypt(intValue, ops, salt);
|
|
||||||
return UnsafeUtility.As<int, float>(ref decValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
public double Encrypt(double value, int ops, int salt)
|
|
||||||
{
|
|
||||||
long longValue = UnsafeUtility.As<double, long>(ref value);
|
|
||||||
long encValue = Encrypt(longValue, ops, salt);
|
|
||||||
return UnsafeUtility.As<long, double>(ref encValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
public double Decrypt(double value, int ops, int salt)
|
|
||||||
{
|
|
||||||
long longValue = UnsafeUtility.As<double, long>(ref value);
|
|
||||||
long decValue = Decrypt(longValue, ops, salt);
|
|
||||||
return UnsafeUtility.As<long, double>(ref decValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
public unsafe byte[] Encrypt(byte[] bytes, int offset, int length, int ops, int salt)
|
|
||||||
{
|
|
||||||
if (length == 0)
|
|
||||||
{
|
|
||||||
return Array.Empty<byte>();
|
|
||||||
}
|
|
||||||
// align size to 4
|
|
||||||
int align4Length = (length + 3) & ~3;
|
|
||||||
byte[] encInts = new byte[align4Length];
|
|
||||||
Buffer.BlockCopy(bytes, offset, encInts, 0, length);
|
|
||||||
|
|
||||||
int intLength = align4Length >> 2;
|
|
||||||
fixed (byte* intArr = &bytes[0])
|
|
||||||
{
|
|
||||||
for (int i = 0; i < intLength; i++)
|
|
||||||
{
|
|
||||||
int* ele = (int*)intArr + i;
|
|
||||||
*ele = Encrypt(*ele, ops, salt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return encInts;
|
|
||||||
}
|
|
||||||
|
|
||||||
public unsafe byte[] Decrypt(byte[] value, int offset, int length, int ops, int salt)
|
|
||||||
{
|
|
||||||
if (length == 0)
|
|
||||||
{
|
|
||||||
return Array.Empty<byte>();
|
|
||||||
}
|
|
||||||
int align4Length = (length + 3) & ~3;
|
|
||||||
int intLength = align4Length >> 2;
|
|
||||||
byte[] decInts = new byte[align4Length];
|
|
||||||
fixed (byte* intArr = &decInts[0])
|
|
||||||
{
|
|
||||||
for (int i = 0; i < intLength; i++)
|
|
||||||
{
|
|
||||||
int* ele = (int*)intArr + i;
|
|
||||||
*ele = Decrypt(*ele, ops, salt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return decInts;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] Encrypt(byte[] bytes, int ops, int salt)
|
|
||||||
{
|
|
||||||
return Encrypt(bytes, 0, bytes.Length, ops, salt);
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] Encrypt(string value, int ops, int salt)
|
|
||||||
{
|
|
||||||
if (value.Length == 0)
|
|
||||||
{
|
|
||||||
return Array.Empty<byte>();
|
|
||||||
}
|
|
||||||
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(value);
|
|
||||||
return Encrypt(bytes, 0, bytes.Length, ops, salt);
|
|
||||||
}
|
|
||||||
|
|
||||||
public string DecryptString(byte[] value, int offset, int length, int ops, int salt)
|
|
||||||
{
|
|
||||||
if (length == 0)
|
|
||||||
{
|
|
||||||
return string.Empty;
|
|
||||||
}
|
|
||||||
return System.Text.Encoding.UTF8.GetString(Decrypt(value, offset, length, ops, salt));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Text;
|
||||||
|
using Unity.Collections.LowLevel.Unsafe;
|
||||||
|
using UnityEngine.Assertions;
|
||||||
|
using UnityEngine.UIElements;
|
||||||
|
|
||||||
|
namespace Obfuz.Encryption
|
||||||
|
{
|
||||||
|
|
||||||
|
public class EncryptionVirtualMachineSimulator : EncryptorBase
|
||||||
|
{
|
||||||
|
private readonly EncryptOpCode[] _opCodes;
|
||||||
|
private readonly int[] _secretKey;
|
||||||
|
|
||||||
|
public EncryptionVirtualMachineSimulator(EncryptOpCode[] opCodes, int[] secretKey)
|
||||||
|
{
|
||||||
|
_opCodes = opCodes;
|
||||||
|
// should be power of 2
|
||||||
|
Assert.AreEqual(0, opCodes.Length ^ (opCodes.Length - 1));
|
||||||
|
_secretKey = secretKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<ushort> DecodeOps(int ops)
|
||||||
|
{
|
||||||
|
var codes = new List<ushort>();
|
||||||
|
while (ops > 0)
|
||||||
|
{
|
||||||
|
var code = (ushort)(ops % _opCodes.Length);
|
||||||
|
codes.Add(code);
|
||||||
|
ops >>= 16;
|
||||||
|
}
|
||||||
|
return codes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int Encrypt(int value, int ops, int salt)
|
||||||
|
{
|
||||||
|
var codes = DecodeOps(ops);
|
||||||
|
foreach (var code in codes)
|
||||||
|
{
|
||||||
|
var opCode = _opCodes[code];
|
||||||
|
value = opCode.Encrypt(value, _secretKey, salt);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int Decrypt(int value, int ops, int salt)
|
||||||
|
{
|
||||||
|
var codes = DecodeOps(ops);
|
||||||
|
for (int i = codes.Count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
var opCode = _opCodes[codes[i]];
|
||||||
|
value = opCode.Decrypt(value, _secretKey, salt);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
namespace Obfuz.Encryption
|
||||||
|
{
|
||||||
|
public interface IVirtualMachineCreator
|
||||||
|
{
|
||||||
|
VirtualMachine CreateVirtualMachine(int opCodeCount, int vmSeed);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
using Obfuz.Utils;
|
||||||
|
using UnityEngine.Assertions;
|
||||||
|
|
||||||
|
namespace Obfuz.Encryption
|
||||||
|
{
|
||||||
|
public class RandomVirtualMachineCreator : IVirtualMachineCreator
|
||||||
|
{
|
||||||
|
private readonly int[] _debugSecretKey;
|
||||||
|
|
||||||
|
public RandomVirtualMachineCreator()
|
||||||
|
{
|
||||||
|
_debugSecretKey = new int[VirtualMachine.SecretKeyLength];
|
||||||
|
for (int i = 0; i < _debugSecretKey.Length; i++)
|
||||||
|
{
|
||||||
|
_debugSecretKey[i] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEncryptInstruction CreateRandomInstruction(IRandom random, int secretKeyLength)
|
||||||
|
{
|
||||||
|
switch (random.NextInt(3))
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
return new AddInstruction(random.NextInt(), random.NextInt(secretKeyLength));
|
||||||
|
case 1:
|
||||||
|
return new XorInstruction(random.NextInt(), random.NextInt(secretKeyLength));
|
||||||
|
case 2:
|
||||||
|
return new BitRotateInstruction(random.NextInt(32), random.NextInt(secretKeyLength));
|
||||||
|
default:
|
||||||
|
throw new System.Exception("Invalid instruction type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private EncryptOpCode CreateEncryptOpCode(ushort code, IRandom r, int opCodeCount)
|
||||||
|
{
|
||||||
|
Assert.IsTrue(code < opCodeCount);
|
||||||
|
var insts = new IEncryptInstruction[opCodeCount];
|
||||||
|
for (int i = 0; i < insts.Length; i++)
|
||||||
|
{
|
||||||
|
IEncryptInstruction inst = CreateRandomInstruction(r, VirtualMachine.SecretKeyLength);
|
||||||
|
Assert.AreEqual(1234, inst.Decrypt(inst.Encrypt(1234, _debugSecretKey, i), _debugSecretKey, i));
|
||||||
|
insts[i] = CreateRandomInstruction(r, opCodeCount);
|
||||||
|
}
|
||||||
|
var function = new EncryptFunction(insts);
|
||||||
|
Assert.AreEqual(1234, function.Decrypt(function.Encrypt(1234, _debugSecretKey, code), _debugSecretKey, code));
|
||||||
|
return new EncryptOpCode(code, function);
|
||||||
|
}
|
||||||
|
|
||||||
|
public VirtualMachine CreateVirtualMachine(int opCodeCount, int vmSeed)
|
||||||
|
{
|
||||||
|
Assert.IsTrue(opCodeCount > 0);
|
||||||
|
Assert.AreEqual(0, opCodeCount ^ (opCodeCount - 1));
|
||||||
|
IRandom r = new RandomWithKey(new byte[] {1,2,3,4,5,6}, vmSeed);
|
||||||
|
var opCodes = new EncryptOpCode[opCodeCount];
|
||||||
|
for (int i = 0; i < opCodes.Length; i++)
|
||||||
|
{
|
||||||
|
opCodes[i] = CreateEncryptOpCode((ushort)i, r, opCodeCount);
|
||||||
|
}
|
||||||
|
return new VirtualMachine(vmSeed, opCodes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
namespace Obfuz.Encryption
|
||||||
|
{
|
||||||
|
public class VirtualMachine
|
||||||
|
{
|
||||||
|
public const int SecretKeyLength = 1024;
|
||||||
|
|
||||||
|
public readonly int vmSeed;
|
||||||
|
public readonly EncryptOpCode[] opCodes;
|
||||||
|
|
||||||
|
public VirtualMachine(int vmSeed, EncryptOpCode[] opCodes)
|
||||||
|
{
|
||||||
|
this.vmSeed = vmSeed;
|
||||||
|
this.opCodes = opCodes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -68,7 +68,7 @@ namespace Obfuz
|
||||||
|
|
||||||
|
|
||||||
var random = new RandomWithKey(_secretKey, _globalRandomSeed);
|
var random = new RandomWithKey(_secretKey, _globalRandomSeed);
|
||||||
var encryptor = new DefaultEncryptor(_secretKey);
|
var encryptor = new NullEncryptor(_secretKey);
|
||||||
var rvaDataAllocator = new RvaDataAllocator(random, encryptor);
|
var rvaDataAllocator = new RvaDataAllocator(random, encryptor);
|
||||||
var constFieldAllocator = new ConstFieldAllocator(encryptor, random, rvaDataAllocator);
|
var constFieldAllocator = new ConstFieldAllocator(encryptor, random, rvaDataAllocator);
|
||||||
_ctx = new ObfuscationPassContext
|
_ctx = new ObfuscationPassContext
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Obfuz.Settings
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
public class EncryptionVMSettings
|
||||||
|
{
|
||||||
|
[Tooltip("secret key for generating encryption virtual machine source code")]
|
||||||
|
public string codeGenerationSecretKey = "Obfuz";
|
||||||
|
|
||||||
|
[Tooltip("encryption virtual machine source code output dir")]
|
||||||
|
public string codeOutputDir = "Assets/Obfuz";
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,6 +32,9 @@ namespace Obfuz.Settings
|
||||||
[Tooltip("global random seed")]
|
[Tooltip("global random seed")]
|
||||||
public int globalRandomSeed = 0;
|
public int globalRandomSeed = 0;
|
||||||
|
|
||||||
|
[Tooltip("encryption virtual machine settings")]
|
||||||
|
public EncryptionVMSettings encryptionVMSettings;
|
||||||
|
|
||||||
[Tooltip("symbol obfuscation settings")]
|
[Tooltip("symbol obfuscation settings")]
|
||||||
public SymbolObfusSettings symbolObfusSettings;
|
public SymbolObfusSettings symbolObfusSettings;
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,8 @@ namespace Obfuz.Settings
|
||||||
private SerializedProperty _secretKey;
|
private SerializedProperty _secretKey;
|
||||||
private SerializedProperty _globalRandomSeed;
|
private SerializedProperty _globalRandomSeed;
|
||||||
|
|
||||||
|
private SerializedProperty _encryptionVMSettings;
|
||||||
|
|
||||||
private SerializedProperty _symbolObfusSettings;
|
private SerializedProperty _symbolObfusSettings;
|
||||||
private SerializedProperty _constEncryptSettings;
|
private SerializedProperty _constEncryptSettings;
|
||||||
private SerializedProperty _fieldEncryptSettings;
|
private SerializedProperty _fieldEncryptSettings;
|
||||||
|
@ -71,6 +73,8 @@ namespace Obfuz.Settings
|
||||||
_secretKey = _serializedObject.FindProperty("secretKey");
|
_secretKey = _serializedObject.FindProperty("secretKey");
|
||||||
_globalRandomSeed = _serializedObject.FindProperty("globalRandomSeed");
|
_globalRandomSeed = _serializedObject.FindProperty("globalRandomSeed");
|
||||||
|
|
||||||
|
_encryptionVMSettings = _serializedObject.FindProperty("encryptionVMSettings");
|
||||||
|
|
||||||
_symbolObfusSettings = _serializedObject.FindProperty("symbolObfusSettings");
|
_symbolObfusSettings = _serializedObject.FindProperty("symbolObfusSettings");
|
||||||
_constEncryptSettings = _serializedObject.FindProperty("constEncryptSettings");
|
_constEncryptSettings = _serializedObject.FindProperty("constEncryptSettings");
|
||||||
_fieldEncryptSettings = _serializedObject.FindProperty("fieldEncryptSettings");
|
_fieldEncryptSettings = _serializedObject.FindProperty("fieldEncryptSettings");
|
||||||
|
@ -95,6 +99,8 @@ namespace Obfuz.Settings
|
||||||
EditorGUILayout.PropertyField(_secretKey);
|
EditorGUILayout.PropertyField(_secretKey);
|
||||||
EditorGUILayout.PropertyField(_globalRandomSeed);
|
EditorGUILayout.PropertyField(_globalRandomSeed);
|
||||||
|
|
||||||
|
EditorGUILayout.PropertyField(_encryptionVMSettings);
|
||||||
|
|
||||||
EditorGUILayout.PropertyField(_symbolObfusSettings);
|
EditorGUILayout.PropertyField(_symbolObfusSettings);
|
||||||
EditorGUILayout.PropertyField(_constEncryptSettings);
|
EditorGUILayout.PropertyField(_constEncryptSettings);
|
||||||
EditorGUILayout.PropertyField(_fieldEncryptSettings);
|
EditorGUILayout.PropertyField(_fieldEncryptSettings);
|
||||||
|
|
|
@ -15,7 +15,7 @@ namespace Obfuz.Settings
|
||||||
[Tooltip("prefix for obfuscated name to avoid name confliction with original name")]
|
[Tooltip("prefix for obfuscated name to avoid name confliction with original name")]
|
||||||
public string obfuscatedNamePrefix = "$";
|
public string obfuscatedNamePrefix = "$";
|
||||||
|
|
||||||
[Tooltip("obfuscate same namespace to same name")]
|
[Tooltip("obfuscate same namespace to one name")]
|
||||||
public bool useConsistentNamespaceObfuscation = true;
|
public bool useConsistentNamespaceObfuscation = true;
|
||||||
|
|
||||||
[Tooltip("path of mapping.xml")]
|
[Tooltip("path of mapping.xml")]
|
||||||
|
|
|
@ -1,102 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Obfuz
|
|
||||||
{
|
|
||||||
public class DefaultEncryptor : IEncryptor
|
|
||||||
{
|
|
||||||
private readonly byte[] _key;
|
|
||||||
|
|
||||||
public DefaultEncryptor(byte[] key)
|
|
||||||
{
|
|
||||||
_key = key;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void EncryptBlock(byte[] data, long ops, int salt)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < data.Length; i++)
|
|
||||||
{
|
|
||||||
data[i] ^= (byte)(_key[i % _key.Length] ^ salt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DecryptBlock(byte[] data, long ops, int salt)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < data.Length; i++)
|
|
||||||
{
|
|
||||||
data[i] ^= (byte)(_key[i % _key.Length] ^ salt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Encrypt(int value, int opts, int salt)
|
|
||||||
{
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Decrypt(int value, int opts, int salt)
|
|
||||||
{
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long Encrypt(long value, int opts, int salt)
|
|
||||||
{
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long Decrypt(long value, int opts, int salt)
|
|
||||||
{
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float Encrypt(float value, int opts, int salt)
|
|
||||||
{
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float Decrypt(float value, int opts, int salt)
|
|
||||||
{
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double Encrypt(double value, int opts, int salt)
|
|
||||||
{
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double Decrypt(double value, int opts, int salt)
|
|
||||||
{
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] Encrypt(byte[] value, int offset, int length, int opts, int salt)
|
|
||||||
{
|
|
||||||
int align4Length = (length + 3) & ~3;
|
|
||||||
var encryptedBytes = new byte[align4Length];
|
|
||||||
Buffer.BlockCopy(value, offset, encryptedBytes, 0, length);
|
|
||||||
return encryptedBytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] Decrypt(byte[] value, int offset, int length, int ops, int salt)
|
|
||||||
{
|
|
||||||
byte[] byteArr = new byte[length];
|
|
||||||
Buffer.BlockCopy(value, 0, byteArr, 0, length);
|
|
||||||
return byteArr;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] Encrypt(string value, int ops, int salt)
|
|
||||||
{
|
|
||||||
byte[] bytes = Encoding.UTF8.GetBytes(value);
|
|
||||||
return Encrypt(bytes, 0, bytes.Length, ops, salt);
|
|
||||||
}
|
|
||||||
|
|
||||||
public string DecryptString(byte[] value, int offset, int length, int ops, int salt)
|
|
||||||
{
|
|
||||||
byte[] bytes = new byte[length];
|
|
||||||
Buffer.BlockCopy(value, 0, bytes, 0, length);
|
|
||||||
return Encoding.UTF8.GetString(bytes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -8,14 +8,14 @@ namespace Obfuz
|
||||||
{
|
{
|
||||||
public static class EncryptionService
|
public static class EncryptionService
|
||||||
{
|
{
|
||||||
private static readonly IEncryptor _encryptor = new DefaultEncryptor(new byte[] { 0x1A, 0x2B, 0x3C, 0x4D });
|
private static readonly IEncryptor _encryptor = new NullEncryptor(new byte[] { 0x1A, 0x2B, 0x3C, 0x4D });
|
||||||
|
|
||||||
public static void EncryptBlock(byte[] data, long ops, int salt)
|
public static void EncryptBlock(byte[] data, int ops, int salt)
|
||||||
{
|
{
|
||||||
_encryptor.EncryptBlock(data, ops, salt);
|
_encryptor.EncryptBlock(data, ops, salt);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void DecryptBlock(byte[] data, long ops, int salt)
|
public static void DecryptBlock(byte[] data, int ops, int salt)
|
||||||
{
|
{
|
||||||
_encryptor.DecryptBlock(data, ops, salt);
|
_encryptor.DecryptBlock(data, ops, salt);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,215 @@
|
||||||
|
using System;
|
||||||
|
using System.Text;
|
||||||
|
using Unity.Collections.LowLevel.Unsafe;
|
||||||
|
|
||||||
|
namespace Obfuz
|
||||||
|
{
|
||||||
|
public abstract class EncryptorBase : IEncryptor
|
||||||
|
{
|
||||||
|
public abstract int Encrypt(int value, int opts, int salt);
|
||||||
|
public abstract int Decrypt(int value, int opts, int salt);
|
||||||
|
|
||||||
|
public virtual long Encrypt(long value, int opts, int salt)
|
||||||
|
{
|
||||||
|
int low = (int)value;
|
||||||
|
int high = (int)(value >> 32);
|
||||||
|
int encryptedLow = Encrypt(low, opts, salt);
|
||||||
|
int encryptedHigh = Encrypt(high, opts, salt);
|
||||||
|
return ((long)encryptedHigh << 32) | (uint)encryptedLow;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual long Decrypt(long value, int opts, int salt)
|
||||||
|
{
|
||||||
|
int low = (int)value;
|
||||||
|
int high = (int)(value >> 32);
|
||||||
|
int decryptedLow = Decrypt(low, opts, salt);
|
||||||
|
int decryptedHigh = Decrypt(high, opts, salt);
|
||||||
|
return ((long)decryptedHigh << 32) | (uint)decryptedLow;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual float Encrypt(float value, int opts, int salt)
|
||||||
|
{
|
||||||
|
ref int intValue = ref UnsafeUtility.As<float, int>(ref value);
|
||||||
|
intValue = Encrypt(intValue, opts, salt);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual float Decrypt(float value, int opts, int salt)
|
||||||
|
{
|
||||||
|
ref int intValue = ref UnsafeUtility.As<float, int>(ref value);
|
||||||
|
intValue = Decrypt(intValue, opts, salt);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual double Encrypt(double value, int opts, int salt)
|
||||||
|
{
|
||||||
|
ref long longValue = ref UnsafeUtility.As<double, long>(ref value);
|
||||||
|
longValue = Encrypt(longValue, opts, salt);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual double Decrypt(double value, int opts, int salt)
|
||||||
|
{
|
||||||
|
ref long longValue = ref UnsafeUtility.As<double, long>(ref value);
|
||||||
|
longValue = Decrypt(longValue, opts, salt);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual unsafe byte[] Encrypt(byte[] value, int offset, int length, int ops, int salt)
|
||||||
|
{
|
||||||
|
if (length == 0)
|
||||||
|
{
|
||||||
|
return Array.Empty<byte>();
|
||||||
|
}
|
||||||
|
|
||||||
|
var encryptedBytes = new byte[length];
|
||||||
|
int intArrLength = length >> 2;
|
||||||
|
|
||||||
|
// align to 4
|
||||||
|
if ((offset & 0x3) != 0)
|
||||||
|
{
|
||||||
|
Buffer.BlockCopy(value, offset, encryptedBytes, 0, length);
|
||||||
|
|
||||||
|
// encrypt int
|
||||||
|
|
||||||
|
fixed (byte* dstBytePtr = &encryptedBytes[0])
|
||||||
|
{
|
||||||
|
int* dstIntPtr = (int*)dstBytePtr;
|
||||||
|
|
||||||
|
for (int i = 0; i < intArrLength; i++)
|
||||||
|
{
|
||||||
|
dstIntPtr[i] = Encrypt(dstIntPtr[i], ops, salt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = intArrLength * 4; i < length; i++)
|
||||||
|
{
|
||||||
|
encryptedBytes[i] = (byte)(encryptedBytes[i] ^ salt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// encrypt int
|
||||||
|
fixed (byte* srcBytePtr = &value[offset])
|
||||||
|
{
|
||||||
|
fixed (byte* dstBytePtr = &encryptedBytes[0])
|
||||||
|
{
|
||||||
|
int* srcIntPtr = (int*)srcBytePtr;
|
||||||
|
int* dstIntPtr = (int*)dstBytePtr;
|
||||||
|
|
||||||
|
for (int i = 0; i < intArrLength; i++)
|
||||||
|
{
|
||||||
|
dstIntPtr[i] = Encrypt(srcIntPtr[i], ops, salt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = intArrLength * 4; i < length; i++)
|
||||||
|
{
|
||||||
|
encryptedBytes[i] = (byte)(value[offset + i] ^ salt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return encryptedBytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public unsafe virtual byte[] Decrypt(byte[] value, int offset, int length, int ops, int salt)
|
||||||
|
{
|
||||||
|
var decryptedBytes = new byte[length];
|
||||||
|
int intArrLength = length >> 2;
|
||||||
|
|
||||||
|
// align to 4
|
||||||
|
if ((offset & 0x3) != 0)
|
||||||
|
{
|
||||||
|
Buffer.BlockCopy(value, offset, decryptedBytes, 0, length);
|
||||||
|
|
||||||
|
// encrypt int
|
||||||
|
|
||||||
|
fixed (byte* dstBytePtr = &decryptedBytes[0])
|
||||||
|
{
|
||||||
|
int* dstIntPtr = (int*)dstBytePtr;
|
||||||
|
|
||||||
|
for (int i = 0; i < intArrLength; i++)
|
||||||
|
{
|
||||||
|
dstIntPtr[i] = Decrypt(dstIntPtr[i], ops, salt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = intArrLength * 4; i < length; i++)
|
||||||
|
{
|
||||||
|
decryptedBytes[i] = (byte)(decryptedBytes[i] ^ salt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// encrypt int
|
||||||
|
fixed (byte* srcBytePtr = &value[offset])
|
||||||
|
{
|
||||||
|
fixed (byte* dstBytePtr = &decryptedBytes[0])
|
||||||
|
{
|
||||||
|
int* srcIntPtr = (int*)srcBytePtr;
|
||||||
|
int* dstIntPtr = (int*)dstBytePtr;
|
||||||
|
|
||||||
|
for (int i = 0; i < intArrLength; i++)
|
||||||
|
{
|
||||||
|
dstIntPtr[i] = Decrypt(srcIntPtr[i], ops, salt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = intArrLength * 4; i < length; i++)
|
||||||
|
{
|
||||||
|
decryptedBytes[i] = (byte)(value[offset + i] ^ salt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return decryptedBytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual byte[] Encrypt(string value, int ops, int salt)
|
||||||
|
{
|
||||||
|
byte[] bytes = Encoding.UTF8.GetBytes(value);
|
||||||
|
return Encrypt(bytes, 0, bytes.Length, ops, salt);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual string DecryptString(byte[] value, int offset, int length, int ops, int salt)
|
||||||
|
{
|
||||||
|
byte[] bytes = Decrypt(value, offset, length, ops, salt);
|
||||||
|
return Encoding.UTF8.GetString(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual unsafe void EncryptBlock(byte[] data, int ops, int salt)
|
||||||
|
{
|
||||||
|
int length = data.Length;
|
||||||
|
int intArrLength = length >> 2;
|
||||||
|
|
||||||
|
fixed (byte* dstBytePtr = &data[0])
|
||||||
|
{
|
||||||
|
int* dstIntPtr = (int*)dstBytePtr;
|
||||||
|
|
||||||
|
for (int i = 0; i < intArrLength; i++)
|
||||||
|
{
|
||||||
|
dstIntPtr[i] = Encrypt(dstIntPtr[i], ops, salt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = intArrLength * 4; i < length; i++)
|
||||||
|
{
|
||||||
|
data[i] = (byte)(data[i] ^ salt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual unsafe void DecryptBlock(byte[] data, int ops, int salt)
|
||||||
|
{
|
||||||
|
int length = data.Length;
|
||||||
|
int intArrLength = length >> 2;
|
||||||
|
|
||||||
|
fixed (byte* dstBytePtr = &data[0])
|
||||||
|
{
|
||||||
|
int* dstIntPtr = (int*)dstBytePtr;
|
||||||
|
|
||||||
|
for (int i = 0; i < intArrLength; i++)
|
||||||
|
{
|
||||||
|
dstIntPtr[i] = Decrypt(dstIntPtr[i], ops, salt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = intArrLength * 4; i < length; i++)
|
||||||
|
{
|
||||||
|
data[i] = (byte)(data[i] ^ salt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,15 +1,13 @@
|
||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Obfuz
|
namespace Obfuz
|
||||||
{
|
{
|
||||||
public interface IEncryptor
|
public interface IEncryptor
|
||||||
{
|
{
|
||||||
void EncryptBlock(byte[] data, long ops, int salt);
|
void EncryptBlock(byte[] data, int ops, int salt);
|
||||||
void DecryptBlock(byte[] data, long ops, int salt);
|
void DecryptBlock(byte[] data, int ops, int salt);
|
||||||
|
|
||||||
int Encrypt(int value, int opts, int salt);
|
int Encrypt(int value, int opts, int salt);
|
||||||
int Decrypt(int value, int opts, int salt);
|
int Decrypt(int value, int opts, int salt);
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Obfuz
|
||||||
|
{
|
||||||
|
public class NullEncryptor : EncryptorBase
|
||||||
|
{
|
||||||
|
private readonly byte[] _key;
|
||||||
|
|
||||||
|
public NullEncryptor(byte[] key)
|
||||||
|
{
|
||||||
|
_key = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int Encrypt(int value, int opts, int salt)
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int Decrypt(int value, int opts, int salt)
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override long Encrypt(long value, int opts, int salt)
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override long Decrypt(long value, int opts, int salt)
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override float Encrypt(float value, int opts, int salt)
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override float Decrypt(float value, int opts, int salt)
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override double Encrypt(double value, int opts, int salt)
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override double Decrypt(double value, int opts, int salt)
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override byte[] Encrypt(byte[] value, int offset, int length, int opts, int salt)
|
||||||
|
{
|
||||||
|
if (length == 0)
|
||||||
|
{
|
||||||
|
return Array.Empty<byte>();
|
||||||
|
}
|
||||||
|
var encryptedBytes = new byte[length];
|
||||||
|
Buffer.BlockCopy(value, offset, encryptedBytes, 0, length);
|
||||||
|
return encryptedBytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override byte[] Decrypt(byte[] value, int offset, int length, int ops, int salt)
|
||||||
|
{
|
||||||
|
if (length == 0)
|
||||||
|
{
|
||||||
|
return Array.Empty<byte>();
|
||||||
|
}
|
||||||
|
byte[] byteArr = new byte[length];
|
||||||
|
Buffer.BlockCopy(value, 0, byteArr, 0, length);
|
||||||
|
return byteArr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override byte[] Encrypt(string value, int ops, int salt)
|
||||||
|
{
|
||||||
|
return Encoding.UTF8.GetBytes(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string DecryptString(byte[] value, int offset, int length, int ops, int salt)
|
||||||
|
{
|
||||||
|
return Encoding.UTF8.GetString(value, offset, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue