16轮运算TEA加密算法C#源代码

public static class Tea

{

public static byte[] Encrypt(byte[] data, byte[] key) {

byte[] dataBytes;

if (data.Length % 2 == 0) {

dataBytes = data;

} else {

dataBytes = new byte[data.Length + 1];

Array.Copy(data,0,dataBytes,0,data.Length);

dataBytes[data.Length] = 0x0;

}

 

byte[] result = new byte[dataBytes.Length * 4];

 

uint[] formattedKey = FormatKey(key);

uint[] tempData = new uint[2];

for (int i = 0; i < dataBytes.Length; i += 2) {

tempData[0] = dataBytes[i];

tempData[1] = dataBytes[i + 1];

code(tempData, formattedKey);

Array.Copy(ConvertUIntToByteArray(tempData[0]),0,result,i * 4,4);

Array.Copy(ConvertUIntToByteArray(tempData[1]),0,result,i*4+4,4);

}

 

return result;

}

 

public static byte[] Decrypt(byte[] data, byte[] key) {

uint[] formattedKey = FormatKey(key);

 

int x = 0;

uint[] tempData = new uint[2];

byte[] dataBytes = new byte[data.Length / 8 * 2];

for (int i = 0; i < data.Length; i += 8) {

tempData[0] = ConvertByteArrayToUInt(data, i);

tempData[1] = ConvertByteArrayToUInt(data, i + 4);

decode(tempData, formattedKey);

dataBytes[x++] = (byte)tempData[0];

dataBytes[x++] = (byte)tempData[1];

}

//修剪添加的空字符

if (dataBytes[dataBytes.Length - 1] == 0x0) {

byte[] result = new byte[dataBytes.Length - 1];

Array.Copy(dataBytes,0,result,0,dataBytes.Length - 1);

}

return dataBytes;

}

 

static uint[] FormatKey(byte[] key) {

if (key.Length == 0)

throw new ArgumentException("Key must be between 1 and 16 characters in length");

byte[] refineKey =new byte[16];

 

if (key.Length < 16) {

Array.Copy(key, 0, refineKey, 0, key.Length);

for (int k = key.Length; k < 16; k++) {

refineKey[k] = 0x20;

}

} else {

Array.Copy(key,0,refineKey,0,16);

}

 

uint[] formattedKey = new uint[4];

 

int j = 0;

for (int i = 0; i < refineKey.Length; i += 4)

formattedKey[j++] = ConvertByteArrayToUInt(refineKey, i);

 

return formattedKey;

}

 

#region Tea Algorithm

static void code(uint[] v, uint[] k) {

uint y = v[0];

uint z = v[1];

uint sum = 0;

uint delta = 0x9e3779b9;

uint n = 16;

 

while (n-- > 0) {

sum += delta;

y += (z << 4) + k[0] ^ z + sum ^ (z >> 5) + k[1];

z += (y << 4) + k[2] ^ y + sum ^ (y >> 5) + k[3];

}

 

v[0] = y;

v[1] = z;

}

 

static void decode(uint[] v, uint[] k) {

uint n = 16;

uint sum;

uint y = v[0];

uint z = v[1];

uint delta = 0x9e3779b9;

/*

* 由于进行16轮运算,所以将delta左移4位,减16次后刚好为0.

*/

sum = delta << 4;

 

while (n-- > 0) {

z -= (y << 4) + k[2] ^ y + sum ^ (y >> 5) + k[3];

y -= (z << 4) + k[0] ^ z + sum ^ (z >> 5) + k[1];

sum -= delta;

}

 

v[0] = y;

v[1] = z;

}

#endregion

 

private static byte[] ConvertUIntToByteArray(uint v) {

byte[] result = new byte[4];

result[0] = (byte)(v & 0xFF);

result[1] = (byte)((v >> 8) & 0xFF);

result[2] = (byte)((v >> 16) & 0xFF);

result[3] = (byte)((v >> 24) & 0xFF);

return result;

}

private static uint ConvertByteArrayToUInt(byte[] v, int offset) {

if (offset + 4 > v.Length) return 0;

 

uint output;

output = (uint)v[offset];

output |= (uint)(v[offset + 1] << 8);

output |= (uint)(v[offset + 2] << 16);

output |= (uint)(v[offset + 3] << 24);

return output;

}

}

如果要改成标准的32轮运算TEA,只需修改code和decode中的n为32,并将decode中的delta左移4位改成左移5位即可。

-------------------------------------

作为一种分组加密算法,TEA加密算法在其发展的过程中,目前出现了几种针对TEA算法设计的缺陷攻击方法,使得原有的TEA加密算法变得不安全,在过去的十几年中,TEA算法进行了若干次的改进,历经XTEA, Block TEA, XXTEA几个版本。目前最新的算法是XXTEA。

 

QQ采用了最初的TEA算法做其核心的加密算法,QQ在采用TEA算法时采用了16轮的加密,其加密复杂度比32轮减了许多。利用TEA算法的设计缺陷,使得快速破解QQ密码成为可能。

 

值得一提的QQ在利用TEA算法做加密时,采用了交织及随机填充随机数的技术,增加了密码分析者分析难度,从一定程度上保护了信息的安全。

QQ在进行TEA加密前采用ntohl函数对原文数据和加密密钥进行了变换,从网络字节顺序转换位主机字节顺序进行加密后,再通过htonl函数将数据转换为网络字节顺序的数据。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值