1. 程式人生 > >遊戲伺服器之加密

遊戲伺服器之加密

根據網上的一個叫Xtea的演算法修改的加密演算法

維基上說的是需要2115.15秒來破解64輪加密的27輪。基本上說在沒有key的情況下,64輪是不可破的。這裡的程式碼只要把ROUND 的16換成64輪就可以。對於遊戲的話,個人覺得16輪差不多,效率可以好些。

攻擊記錄:In 2004, Ko et al. presented a related-keydifferential attack on 27 out of 64 rounds of XTEA, requiring 220.5chosen plaintexts and a time complexity of 2115.15 (Ko et al., 2004)



參考:

#include <stdio.h>
#include <string.h>


#define ROUND (64)//輪數可修改成16
unsigned int delta=0x8A3778B5;                  /* a key schedule constant 0x9E3779B9 */
#define STEP (8)//每次加密8位元組,因為每次加密兩個unsigned int(前端只支援最大4位元組的變數)


#define CHANGE_ENCRYPT (0)


typedef unsigned int uint32_t;


static void realEncrypt(unsigned int *v, unsigned int *k) {
#if CHANGE_ENCRYPT
unsigned int y=v[0], z=v[1], i,sum = 0;         /* set up */
static const unsigned int a=k[0], b=k[1], c=k[2], d=k[3];   /* cache key */
for (i=0; i < ROUND; i++) {                        /* basic cycle start */
sum += delta;
y += ((z<<4) + a) ^ (z + delta) ^ ((z>>5) + b);
z += ((y<<4) + c) ^ (y + delta) ^ ((y>>5) + d);/* end cycle */
}
v[0]=y;
v[1]=z;
#else
unsigned int i;
uint32_t v0=v[0], v1=v[1], sum=0;
for (i=0; i < ROUND; i++) {
v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);
sum += delta;
v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]);
}
v[0]=v0; v[1]=v1;
#endif
}


static void realDecrypt(unsigned int *v, unsigned int *k) {
#if CHANGE_ENCRYPT
unsigned int y=v[0], z=v[1],i; /* set up */


static const unsigned int a=k[0], b=k[1], c=k[2], d=k[3];    /* cache key */
for(i=0; i<ROUND; i++) {                            /* basic cycle start */
z -= ((y<<4) + c) ^ (y + delta) ^ ((y>>5) + d);
y -= ((z<<4) + a) ^ (z + delta) ^ ((z>>5) + b);
}
v[0]=y;
v[1]=z;
#else
unsigned int i;
uint32_t v0=v[0], v1=v[1],  sum=delta*ROUND;
for (i=0; i < ROUND; i++) {
v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]);
sum -= delta;
v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);
}
v[0]=v0; v[1]=v1;
#endif
}


void encrypt(char* src,int srclen,const char* key)
{
char* pSrc = src;
while(srclen>=STEP)//每次加密8位元組
{
realEncrypt((unsigned int *)pSrc,(unsigned int *)key);
pSrc += STEP;
srclen -= STEP;
}
}


void decrypt(char* src,int srclen,const char* key)
{
char* pSrc = src;
while(srclen>=STEP)//每次解密8位元組
{
realDecrypt((unsigned int *)pSrc,(unsigned int *)key);
pSrc += STEP;
srclen -= STEP;
}
}


int main()
{
char src[] = "ADDEE2DBB3E2DBB3ADDEE2DBB3E2DBB3ADDEE2DBB3E2DBB3";//48位元組
const char key[] = "4BD97521ABE2DBB5";//16位元組的key
//16位元組4BD97521ABE2DBB511D44901F5C6EDB4
int len = strlen(src);
printf("before(%d):%s\n",len,src);
encrypt(src,len,key);
len = strlen(src);
printf("encrypted(%d):%s\n",len,src);
decrypt(src,len,key);
len = strlen(src);
printf("decrypted(%d):%s\n",len,src);
return 0;
}


輸出結果:

before(48):ADDEE2DBB3E2DBB3ADDEE2DBB3E2DBB3ADDEE2DBB3E2DBB3
encrypted(48):Oj
��+���I��Oj
��+���I��Oj
��+���I��
decrypted(48):ADDEE2DBB3E2DBB3ADDEE2DBB3E2DBB3ADDEE2DBB3E2DBB3