using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace SensorHub.Servers { public static class TEA { private static Byte[] TEA_key = new Byte[16] { 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102 }; static void tea_encrypt(ref UInt32 v1, ref UInt32 v2, UInt32 a, UInt32 b, UInt32 c, UInt32 d) { UInt32 y = v1, z = v2, sum = 0, i; UInt32 delta = 0x9e3779b9; //UInt32 a = k1, b = k2, c = k3, d = k4; for (i = 0; i < 32; i++) { sum += delta; y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); } v1 = y; v2 = z; } /********************************************************************* * tea解密 *参数:v:要解密的数据,长度为8字节 * k:解密用的key,长度为16字节 **********************************************************************/ static void tea_decrypt(ref UInt32 v1, ref UInt32 v2, UInt32 a, UInt32 b, UInt32 c, UInt32 d) { UInt32 y = v1, z = v2, sum = 0xC6EF3720, i; UInt32 delta = 0x9e3779b9; //UInt32 a = k[0], b = k[1], c = k[2], d = k[3]; for (i = 0; i < 32; i++) { z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); sum -= delta; } v1 = y; v2 = z; } /********************************************************************* * 加密算法 *参数:src:源数据,所占空间必须为8字节的倍数.加密完成后密文也存放在这 * size_src:源数据大小,单位字节 * key:密钥,16字节 *返回:密文的字节数 **********************************************************************/ public static int encrypt(ref Byte[] src, int size_src) { UInt16 a = 0; UInt16 i = 0; int num = 0; //将明文补足为8字节的倍数 a = (UInt16)(size_src % 8); if (a != 0) { for (i = 0; i < 8 - a; i++) { src[size_src++] = 0; } } UInt32 Key1 = (UInt32)(TEA_key[3] << 24 | TEA_key[2] << 16 | TEA_key[1] << 8 | TEA_key[0]); UInt32 Key2 = (UInt32)(TEA_key[7] << 24 | TEA_key[6] << 16 | TEA_key[5] << 8 | TEA_key[4]); UInt32 Key3 = (UInt32)(TEA_key[11] << 24 | TEA_key[10] << 16 | TEA_key[9] << 8 | TEA_key[8]); UInt32 Key4 = (UInt32)(TEA_key[15] << 24 | TEA_key[14] << 16 | TEA_key[13] << 8 | TEA_key[12]); //加密 num = (UInt16)(size_src / 8); for (i = 0; i < num; i++) { //tea_encrypt((UInt32*)(src + i * 8), key); UInt32 src1 = (UInt32)(src[i * 8 + 3] << 24 | src[i * 8 + 2] << 16 | src[i * 8 + 1] << 8 | src[i * 8 + 0]); UInt32 src2 = (UInt32)(src[i * 8 + 7] << 24 | src[i * 8 + 6] << 16 | src[i * 8 + 5] << 8 | src[i * 8 + 4]); tea_encrypt(ref src1, ref src2, Key1, Key2, Key3, Key4); src[i * 8 + 3] = (Byte)(src1 >> 24); src[i * 8 + 2] = (Byte)(src1 >> 16); src[i * 8 + 1] = (Byte)(src1 >> 8); src[i * 8 + 0] = (Byte)(src1); src[i * 8 + 7] = (Byte)(src2 >> 24); src[i * 8 + 6] = (Byte)(src2 >> 16); src[i * 8 + 5] = (Byte)(src2 >> 8); src[i * 8 + 4] = (Byte)(src2); } return size_src; } /********************************************************************* * 解密算法 *参数:src:源数据,所占空间必须为8字节的倍数.解密完成后明文也存放在这 * size_src:源数据大小,单位字节 * key:密钥,16字节 *返回:明文的字节数,如果失败,返回0 **********************************************************************/ public static int decrypt(ref Byte[] src, int size_src) { UInt16 i = 0; UInt16 num = 0; //判断长度是否为8的倍数 if (size_src % 8 != 0) { //printf("\r\nchang du bu shi 8!!"); return 0; } UInt32 Key1 = (UInt32)(TEA_key[3] << 24 | TEA_key[2] << 16 | TEA_key[1] << 8 | TEA_key[0]); UInt32 Key2 = (UInt32)(TEA_key[7] << 24 | TEA_key[6] << 16 | TEA_key[5] << 8 | TEA_key[4]); UInt32 Key3 = (UInt32)(TEA_key[11] << 24 | TEA_key[10] << 16 | TEA_key[9] << 8 | TEA_key[8]); UInt32 Key4 = (UInt32)(TEA_key[15] << 24 | TEA_key[14] << 16 | TEA_key[13] << 8 | TEA_key[12]); //解密 num = (Byte)(size_src / 8); for (i = 0; i < num; i++) { //tea_decrypt((UInt32*)(src + i * 8), (UInt32*)key); UInt32 src1 = (UInt32)(src[i * 8 + 3] << 24 | src[i * 8 + 2] << 16 | src[i * 8 + 1] << 8 | src[i * 8 + 0]); UInt32 src2 = (UInt32)(src[i * 8 + 7] << 24 | src[i * 8 + 6] << 16 | src[i * 8 + 5] << 8 | src[i * 8 + 4]); tea_decrypt(ref src1, ref src2, Key1, Key2, Key3, Key4); src[i * 8 + 3] = (Byte)(src1 >> 24); src[i * 8 + 2] = (Byte)(src1 >> 16); src[i * 8 + 1] = (Byte)(src1 >> 8); src[i * 8 + 0] = (Byte)(src1); src[i * 8 + 7] = (Byte)(src2 >> 24); src[i * 8 + 6] = (Byte)(src2 >> 16); src[i * 8 + 5] = (Byte)(src2 >> 8); src[i * 8 + 4] = (Byte)(src2); } return size_src; } } }