public static void Test() { System.IO.MemoryStream m = new System.IO.MemoryStream(); var b = new System.IO.BinaryWriter(m); for (int i = 0; i < 512; i++) { b.Write((byte)1); b.Write((byte)2); } var buffs = m.GetBuffer(); var index = m.Position; byte[] bs = new byte[index]; for (int i = 0; i < bs.Length; i++) { bs[i] = buffs[i]; } int buffLen = bs.Length; int tempCount = 0; var encBuff = new TeaEncTempBuffer(); var tempBuff = new byte[1420]; NetworkCryptologyUtil.TeaEncrypt(encBuff, bs, buffLen, TestKey, tempBuff, ref tempCount); System.Console.WriteLine(tempCount); System.Console.WriteLine(tempBuff); var data1 = tempBuff.Take(tempCount).ToArray(); tempCount = data1.Length; var decBuff = new TeaDecTempBuffer(); var tempBuff1 = new byte[1420]; NetworkCryptologyUtil.TeaDecrypt(decBuff, data1, tempCount, TestKey, tempBuff1, ref tempCount); System.Console.WriteLine(tempCount); System.Console.WriteLine(tempBuff1); }
static void TeaDecryptECB(TeaDecTempBuffer decTempBuffer, byte[] pInBuf, int inBufIndex, byte[] pKey, byte[] pOutBuf, int outBufIndex) { uint y, z, sum; uint[] k = decTempBuffer.dec_k; int i; y = (uint)System.BitConverter.ToInt32(pInBuf, 0); z = (uint)System.BitConverter.ToInt32(pInBuf, 4); for (i = 0; i < 4; i++) { k[i] = (uint)System.BitConverter.ToInt32(pKey, i * 4); } sum = DELTA << LOG_ROUNDS; for (i = 0; i < ROUNDS; i++) { z -= ((y << 4) + k[2]) ^ (y + sum) ^ ((y >> 5) + k[3]); y -= ((z << 4) + k[0]) ^ (z + sum) ^ ((z >> 5) + k[1]); sum -= DELTA; } IntToBytes((int)y, pOutBuf, outBufIndex); IntToBytes((int)z, pOutBuf, outBufIndex + 4); }
/*pKey为16byte*/ /* * 输入:pInBuf为密文格式,nInBufLen为pInBuf的长度是8byte的倍数; *pOutBufLen为接收缓冲区的长度 * 特别注意*pOutBufLen应预置接收缓冲区的长度! * 输出:pOutBuf为明文(Body),pOutBufLen为pOutBuf的长度,至少应预留nInBufLen-10; * 返回值:如果格式正确返回TRUE; */ /*TEA解密算法,CBC模式*/ /*密文格式:PadLen(1byte)+Padding(var,0-7byte)+Salt(2byte)+Body(var byte)+Zero(7byte)*/ public static bool TeaDecrypt(TeaDecTempBuffer decTempBuffer, byte[] pInBuf, int nInBufLen, byte[] pKey, byte[] pOutBuf, ref int pOutBufLen) { int nPadLen, nPlainLen; byte[] dest_buf = decTempBuffer.dec_dest_buff; byte[] zero_buf = decTempBuffer.dec_zero_buff; byte[] iv_pre_crypt = decTempBuffer.dec_iv_pre; byte[] iv_cur_crypt = decTempBuffer.dec_iv_cur; int dest_i, i, j; //byte[] pInBufBoundary; int nBufPos = 0; int inBufPos = 0; if ((nInBufLen % 8) != 0 || (nInBufLen < 16)) { return(false); } TeaDecryptECB(decTempBuffer, pInBuf, inBufPos, pKey, dest_buf, nBufPos); nPadLen = dest_buf[0] & 0x7 /*只要最低三位*/; /*密文格式:PadLen(1byte)+Padding(var,0-7byte)+Salt(2byte)+Body(var byte)+Zero(7byte)*/ i = nInBufLen - 1 /*PadLen(1byte)*/ - nPadLen - SALT_LEN - ZERO_LEN; /*明文长度*/ if (pOutBufLen < i || (i < 0)) { return(false); } pOutBufLen = i; //pInBufBoundary = pInBuf + nInBufLen; /*输入缓冲区的边界,下面不能pInBuf>=pInBufBoundary*/ for (i = 0; i < 8; i++) { zero_buf[i] = 0; } System.Buffer.BlockCopy(zero_buf, 0, iv_pre_crypt, 0, 8); System.Buffer.BlockCopy(pInBuf, inBufPos, iv_cur_crypt, 0, 8); inBufPos += 8; nBufPos += 8; dest_i = 1; /*dest_i指向dest_buf下一个位置*/ /*把Padding滤掉*/ dest_i += nPadLen; /*dest_i must <=8*/ /*把Salt滤掉*/ for (i = 1; i <= SALT_LEN;) { if (dest_i < 8) { dest_i++; i++; } else if (dest_i == 8) { /*解开一个新的加密块*/ /*改变前一个加密块的指针*/ System.Buffer.BlockCopy(iv_cur_crypt, 0, iv_pre_crypt, 0, 8); System.Buffer.BlockCopy(pInBuf, inBufPos, iv_cur_crypt, 0, 8); /*异或前一块明文(在dest_buf[]中)*/ for (j = 0; j < 8; j++) { if ((nBufPos + j) >= nInBufLen) { return(false); } dest_buf[j] ^= pInBuf[inBufPos + j]; } /*dest_i==8*/ TeaDecryptECB(decTempBuffer, dest_buf, 0, pKey, dest_buf, 0); /*在取出的时候才异或前一块密文(iv_pre_crypt)*/ inBufPos += 8; nBufPos += 8; dest_i = 0; /*dest_i指向dest_buf下一个位置*/ } } /*还原明文*/ int outBufPos = 0; nPlainLen = pOutBufLen; while (nPlainLen > 0) { if (dest_i < 8) { pOutBuf[outBufPos++] = (byte)(dest_buf[dest_i] ^ iv_pre_crypt[dest_i]); dest_i++; nPlainLen--; } else if (dest_i == 8) { /*dest_i==8*/ /*改变前一个加密块的指针*/ System.Buffer.BlockCopy(iv_cur_crypt, 0, iv_pre_crypt, 0, 8); System.Buffer.BlockCopy(pInBuf, inBufPos, iv_cur_crypt, 0, 8); /*解开一个新的加密块*/ /*异或前一块明文(在dest_buf[]中)*/ for (j = 0; j < 8; j++) { if ((nBufPos + j) >= nInBufLen) { return(false); } dest_buf[j] ^= pInBuf[j + inBufPos]; } TeaDecryptECB(decTempBuffer, dest_buf, 0, pKey, dest_buf, 0); /*在取出的时候才异或前一块密文(iv_pre_crypt)*/ inBufPos += 8; nBufPos += 8; dest_i = 0; /*dest_i指向dest_buf下一个位置*/ } } /*校验Zero*/ for (i = 1; i <= ZERO_LEN;) { if (dest_i < 8) { if ((dest_buf[dest_i] ^ iv_pre_crypt[dest_i]) != 0) { return(false); } dest_i++; i++; } else if (dest_i == 8) { /*改变前一个加密块的指针*/ System.Buffer.BlockCopy(iv_cur_crypt, 0, iv_pre_crypt, 0, 8); System.Buffer.BlockCopy(pInBuf, inBufPos, iv_cur_crypt, 0, 8); /*解开一个新的加密块*/ /*异或前一块明文(在dest_buf[]中)*/ for (j = 0; j < 8; j++) { if ((nBufPos + j) >= nInBufLen) { return(false); } dest_buf[j] ^= pInBuf[j + inBufPos]; } TeaDecryptECB(decTempBuffer, dest_buf, 0, pKey, dest_buf, 0); /*在取出的时候才异或前一块密文(iv_pre_crypt)*/ inBufPos += 8; nBufPos += 8; dest_i = 0; /*dest_i指向dest_buf下一个位置*/ } } return(true); }