340 lines
11 KiB
C#
340 lines
11 KiB
C#
|
using System;
|
|||
|
using System.Security.Cryptography;
|
|||
|
|
|||
|
namespace GameLogic
|
|||
|
{
|
|||
|
class Encryptor
|
|||
|
{
|
|||
|
public void Init(byte[] key)
|
|||
|
{
|
|||
|
m_service = new TripleDESCryptoServiceProvider { KeySize = 24 * 8, Padding = System.Security.Cryptography.PaddingMode.PKCS7 };
|
|||
|
m_service.Key = key;
|
|||
|
m_service.Mode = CipherMode.ECB;
|
|||
|
m_Encrypt = m_service.CreateEncryptor();
|
|||
|
m_Decrypt = m_service.CreateDecryptor();
|
|||
|
m_OriginalBuff = new byte[64 * 1024];
|
|||
|
m_bValid = true;
|
|||
|
}
|
|||
|
public void Init(string sKey)
|
|||
|
{
|
|||
|
Init(System.Text.Encoding.UTF8.GetBytes(sKey));
|
|||
|
}
|
|||
|
private int FixEncryDataBlock(byte[] data, int nDataLen)
|
|||
|
{
|
|||
|
int nSize = (nDataLen / 8 + 1) * 8;
|
|||
|
System.Buffer.BlockCopy(data, 0, m_OriginalBuff, 0, nDataLen);
|
|||
|
for (int i = nDataLen; i < nSize; ++i)
|
|||
|
{
|
|||
|
m_OriginalBuff[i] = (byte)(nSize - nDataLen);
|
|||
|
}
|
|||
|
return nSize;
|
|||
|
}
|
|||
|
public byte[] Encode(byte[] szData)
|
|||
|
{
|
|||
|
int nDataLen = szData.Length;
|
|||
|
int nFixLen = FixEncryDataBlock(szData, nDataLen);
|
|||
|
byte[] szOut = new byte[nFixLen];
|
|||
|
m_Encrypt.TransformBlock(m_OriginalBuff, 0, nFixLen, szOut, 0);
|
|||
|
return szOut;
|
|||
|
}
|
|||
|
public byte[] Decode(byte[] szData)
|
|||
|
{
|
|||
|
return m_Decrypt.TransformFinalBlock(szData, 0, szData.Length);
|
|||
|
}
|
|||
|
public bool IsValid()
|
|||
|
{
|
|||
|
return m_bValid;
|
|||
|
}
|
|||
|
public void SetValid(bool bValid)
|
|||
|
{
|
|||
|
m_bValid = bValid;
|
|||
|
}
|
|||
|
private TripleDESCryptoServiceProvider m_service;
|
|||
|
private ICryptoTransform m_Encrypt;
|
|||
|
private ICryptoTransform m_Decrypt;
|
|||
|
private byte[] m_OriginalBuff;
|
|||
|
private bool m_bValid = false;
|
|||
|
}
|
|||
|
|
|||
|
class Crypto : GameLogic.ICrypto
|
|||
|
{
|
|||
|
public void Init(string key)
|
|||
|
{
|
|||
|
encryptor.Init(key);
|
|||
|
}
|
|||
|
|
|||
|
public override byte[] Encode(byte[] data)
|
|||
|
{
|
|||
|
if (data != null && data.Length > 0)
|
|||
|
{
|
|||
|
byte[] compressed = Ionic.Zlib.ZlibStream.CompressBuffer(data);
|
|||
|
return encryptor.Encode(compressed);
|
|||
|
}
|
|||
|
return data;
|
|||
|
}
|
|||
|
|
|||
|
public override byte[] Decode(byte[] data)
|
|||
|
{
|
|||
|
if (data != null && data.Length > 0)
|
|||
|
{
|
|||
|
byte[] decoded = encryptor.Decode(data);
|
|||
|
return Ionic.Zlib.ZlibStream.UncompressBuffer(decoded);
|
|||
|
}
|
|||
|
return data;
|
|||
|
}
|
|||
|
|
|||
|
private Encryptor encryptor = new Encryptor();
|
|||
|
}
|
|||
|
|
|||
|
class TEA
|
|||
|
{
|
|||
|
public static int[] KEY = new int[]{//加密解密所用的KEY
|
|||
|
0x789f5645, unchecked((int)0xf68bd5a4),
|
|||
|
unchecked((int)0x81963ffa), 0x458fac58
|
|||
|
};
|
|||
|
private static int TIMES = 32;
|
|||
|
|
|||
|
|
|||
|
public static int byteToInt(byte[] content, int offset)
|
|||
|
{
|
|||
|
int result = (int)(content[offset + 3]) | (int)(content[offset + 2]) << 8 |
|
|||
|
(int)(content[offset + 1]) << 16 | (int)content[offset] << 24;
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
public static short byteToShort(byte[] content, int offset)
|
|||
|
{
|
|||
|
int result = (int)(content[offset + 1]) | (int)(content[offset]) << 8;
|
|||
|
return (short)result;
|
|||
|
}
|
|||
|
public static void intToByte(byte[] bys, int offset, int content)
|
|||
|
{
|
|||
|
bys[offset + 3] = (byte)(content & 0xff);
|
|||
|
bys[offset + 2] = (byte)((content >> 8) & 0xff);
|
|||
|
bys[offset + 1] = (byte)((content >> 16) & 0xff);
|
|||
|
bys[offset] = (byte)((content >> 24) & 0xff);
|
|||
|
}
|
|||
|
|
|||
|
//加密
|
|||
|
public static byte[] encrypt(byte[] content, int offset, int[] key)
|
|||
|
{
|
|||
|
unchecked
|
|||
|
{
|
|||
|
//times为加密轮数
|
|||
|
int delta = (int)0x9e3779b9; //这是算法标准给的值
|
|||
|
int a = key[0], b = key[1], c = key[2], d = key[3];
|
|||
|
for (int m = offset; m < content.Length; m += 8)
|
|||
|
{
|
|||
|
int y = byteToInt(content, m), z = byteToInt(content, m + 4), sum = 0, i;
|
|||
|
for (i = 0; i < TIMES; i++)
|
|||
|
{
|
|||
|
sum += delta;
|
|||
|
y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
|
|||
|
z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
|
|||
|
}
|
|||
|
intToByte(content, m, y);
|
|||
|
intToByte(content, m + 4, z);
|
|||
|
}
|
|||
|
return content;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public static void shortToByte(byte[] bys, int offset, int content)
|
|||
|
{
|
|||
|
bys[offset + 1] = (byte)(content & 0xff);
|
|||
|
bys[offset] = (byte)((content >> 8) & 0xff);
|
|||
|
}
|
|||
|
|
|||
|
public static byte[] encrypt2(byte[] content, int[] key)
|
|||
|
{
|
|||
|
//8字节对齐,并加上数据长度
|
|||
|
int totalLength = (content.Length + 7) / 8 * 8 + 2;
|
|||
|
byte[] bys = new byte[totalLength];
|
|||
|
Array.Copy(content, 0, bys, 2, content.Length);
|
|||
|
byte[] encryptContent = encrypt(bys, 2, key);
|
|||
|
shortToByte(encryptContent, 0, content.Length);
|
|||
|
return encryptContent;
|
|||
|
}
|
|||
|
|
|||
|
//解密
|
|||
|
public static byte[] decrypt(byte[] encryptContent, int offset, int[] key)
|
|||
|
{
|
|||
|
unchecked
|
|||
|
{
|
|||
|
int delta = (int)0x9e3779b9; //这是算法标准给的值
|
|||
|
int a = key[0], b = key[1], c = key[2], d = key[3];
|
|||
|
for (int m = offset; m < encryptContent.Length; m += 8)
|
|||
|
{
|
|||
|
int y = byteToInt(encryptContent, m), z = byteToInt(encryptContent, m + 4), sum = (int)0xC6EF3720, i;
|
|||
|
for (i = 0; i < TIMES; i++)
|
|||
|
{
|
|||
|
z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
|
|||
|
y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
|
|||
|
sum -= delta;
|
|||
|
}
|
|||
|
intToByte(encryptContent, m, y);
|
|||
|
intToByte(encryptContent, m + 4, z);
|
|||
|
}
|
|||
|
return encryptContent;
|
|||
|
}
|
|||
|
}
|
|||
|
//解密时,encryptContent只是待解密内容
|
|||
|
public static byte[] decrypt2(byte[] encryptContent, int len, int offset, int[] key)
|
|||
|
{
|
|||
|
byte[] decryptContent = decrypt(encryptContent, offset, key);
|
|||
|
if (len == decryptContent.Length)
|
|||
|
{
|
|||
|
return decryptContent;
|
|||
|
}
|
|||
|
Array.Resize<byte>(ref decryptContent, len);
|
|||
|
return decryptContent;
|
|||
|
}
|
|||
|
|
|||
|
public byte[] Decode(byte[] data, int len)
|
|||
|
{
|
|||
|
return decrypt2(data, len, 0, KEY);
|
|||
|
}
|
|||
|
|
|||
|
public byte[] Encode(byte[] message)
|
|||
|
{
|
|||
|
return encrypt2(message, KEY);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
class XXTEA : GameLogic.ICrypto
|
|||
|
{
|
|||
|
//加密解密所用的KEY
|
|||
|
public static uint[] Key = new uint[] {
|
|||
|
0x789f5645, 0xf68bd5a4,
|
|||
|
0x81963ffa, 0x458fac58
|
|||
|
};
|
|||
|
|
|||
|
public override byte[] Encode(byte[] Data)
|
|||
|
{
|
|||
|
if (Data.Length == 0)
|
|||
|
{
|
|||
|
return Data;
|
|||
|
}
|
|||
|
if (Data.Length % 8 != 0)
|
|||
|
{
|
|||
|
byte[] newData = new byte[Data.Length % 8 + Data.Length];
|
|||
|
for (int i = 0; i < newData.Length; i++)
|
|||
|
{
|
|||
|
newData[i] = i < Data.Length ? Data[i] : (byte)0;
|
|||
|
}
|
|||
|
Data = newData;
|
|||
|
}
|
|||
|
return ToByteArray(Encrypt(ToUInt32Array(Data, true), Key), false);
|
|||
|
}
|
|||
|
public override byte[] Decode(byte[] Data)
|
|||
|
{
|
|||
|
if (Data.Length == 0)
|
|||
|
{
|
|||
|
return Data;
|
|||
|
}
|
|||
|
return ToByteArray(Decrypt(ToUInt32Array(Data, false), Key), true);
|
|||
|
}
|
|||
|
|
|||
|
private static uint[] Encrypt(uint[] v, uint[] k)
|
|||
|
{
|
|||
|
int n = v.Length - 1;
|
|||
|
if (n < 1)
|
|||
|
{
|
|||
|
return v;
|
|||
|
}
|
|||
|
if (k.Length < 4)
|
|||
|
{
|
|||
|
uint[] Key = new uint[4];
|
|||
|
k.CopyTo(Key, 0);
|
|||
|
k = Key;
|
|||
|
}
|
|||
|
uint delta = 3; //防止有人通过汇编指令搜索到该常数以至于猜出算法
|
|||
|
uint z = v[n], y = v[0], sum = 0, e;
|
|||
|
int p, q = 6 + 52 / (n + 1);
|
|||
|
delta *= 89; delta *= 523; delta *= 19009;
|
|||
|
while (q-- > 0)
|
|||
|
{
|
|||
|
sum = unchecked(sum + delta);
|
|||
|
e = sum >> 2 & 3;
|
|||
|
for (p = 0; p < n; p++)
|
|||
|
{
|
|||
|
y = v[p + 1];
|
|||
|
z = unchecked(v[p] += (z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z));
|
|||
|
}
|
|||
|
y = v[0];
|
|||
|
z = unchecked(v[n] += (z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z));
|
|||
|
}
|
|||
|
return v;
|
|||
|
}
|
|||
|
private static uint[] Decrypt(uint[] v, uint[] k)
|
|||
|
{
|
|||
|
int n = v.Length - 1;
|
|||
|
if (n < 1)
|
|||
|
{
|
|||
|
return v;
|
|||
|
}
|
|||
|
if (k.Length < 4)
|
|||
|
{
|
|||
|
uint[] Key = new uint[4];
|
|||
|
k.CopyTo(Key, 0);
|
|||
|
k = Key;
|
|||
|
}
|
|||
|
uint delta = 3; //防止有人通过汇编指令搜索到该常数以至于猜出算法
|
|||
|
uint z = v[n], y = v[0], sum, e;
|
|||
|
int p, q = 6 + 52 / (n + 1);
|
|||
|
delta *= 89; delta *= 523; delta *= 19009;
|
|||
|
sum = unchecked((uint)(q * delta));
|
|||
|
while (sum != 0)
|
|||
|
{
|
|||
|
e = sum >> 2 & 3;
|
|||
|
for (p = n; p > 0; p--)
|
|||
|
{
|
|||
|
z = v[p - 1];
|
|||
|
y = unchecked(v[p] -= (z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z));
|
|||
|
}
|
|||
|
z = v[n];
|
|||
|
y = unchecked(v[0] -= (z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z));
|
|||
|
sum = unchecked(sum - delta);
|
|||
|
}
|
|||
|
return v;
|
|||
|
}
|
|||
|
private static uint[] ToUInt32Array(byte[] Data, bool IncludeLength)
|
|||
|
{
|
|||
|
int n = ((Data.Length & 3) == 0) ? (Data.Length >> 2) : ((Data.Length >> 2) + 1);
|
|||
|
uint[] Result;
|
|||
|
if (IncludeLength)
|
|||
|
{
|
|||
|
Result = new uint[n + 1];
|
|||
|
Result[n] = (uint)Data.Length;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
Result = new uint[n];
|
|||
|
}
|
|||
|
n = Data.Length;
|
|||
|
for (int i = 0; i < n; i++)
|
|||
|
{
|
|||
|
Result[i >> 2] |= (uint)Data[i] << ((i & 3) << 3);
|
|||
|
}
|
|||
|
return Result;
|
|||
|
}
|
|||
|
private static byte[] ToByteArray(uint[] Data, bool IncludeLength)
|
|||
|
{
|
|||
|
int n;
|
|||
|
if (IncludeLength)
|
|||
|
{
|
|||
|
n = (int)Data[Data.Length - 1];
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
n = Data.Length << 2;
|
|||
|
}
|
|||
|
byte[] Result = new byte[n];
|
|||
|
for (int i = 0; i < n; i++)
|
|||
|
{
|
|||
|
Result[i] = (byte)(Data[i >> 2] >> ((i & 3) << 3));
|
|||
|
}
|
|||
|
return Result;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|