miduo_client/Assets/LuaFramework/Scripts/Network/Crypto.cs

340 lines
11 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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;
}
}
}