RC5 Decrypt/Encrypt for Conquer game client
RC5.h
#ifndef RC5_H
#define RC5_H
#define RC5_32 32
#define RC5_12 12
#define RC5_SUB (RC5_12*2 + 2)
#define RC5_16 16
#define RC5_KEY (RC5_16/4)
const unsigned long RC5_PW32 = 0xB7E15163;
const unsigned long RC5_QW32 = 0x61C88647;
const unsigned char RC5PASSWORD_KEY[16] = { 0x3C, 0xDC, 0xFE, 0xE8, 0xC4, 0x54, 0xD6, 0x7E,
0x16, 0xA6, 0xF8, 0x1A, 0xE8, 0xD0, 0x38, 0xBE };
const unsigned char RC5BARPASSWORD_KEY[16] = { 0x44, 0xD0, 0xE2, 0xBA, 0x4A, 0x38, 0x14, 0x44,
0x64, 0xE0, 0x12, 0xAE, 0xDA, 0x56, 0x1C, 0xF8 };
////////////////////////////////////////////////////////////////////////////////////////////////
class CRc5
{
public:
void Rc5InitKey(const unsigned char bufKey[RC5_16]);
void Rc5Encrypt(void* buf, int nLen8);
void Rc5Decrypt(void* buf, int nLen8);
protected:
unsigned long m_bufKey[RC5_KEY];
unsigned long m_bufSub[RC5_SUB];
};
#endif // RC5_H
RC5.cpp
#include <string>
#include <assert.h>
#include "RC5.h"
unsigned long rotate_left(unsigned long nData, unsigned long nCount);
unsigned long rotate_right(unsigned long nData, unsigned long nCount);
void CRc5::Rc5InitKey(const unsigned char bufKey[RC5_16])
{
try{
memcpy(m_bufKey, bufKey, RC5_16);
}catch(...) {
#ifdef _DEBUG
assert(!"InitRc5Key()");
#endif
}
/*for (int i = 0; i < 4; i++)
m_bufKey[i] = (long)(bufKey[i * 4] + (bufKey[i * 4 + 1] << 8) + (bufKey[i * 4 + 2] << 16) + (bufKey[i * 4 + 3] << 24));
m_bufSub[0] = RC5_PW32;*/
m_bufSub[0] = RC5_PW32;
for(int i = 1; i<26; i++)
{
m_bufSub[i] = m_bufSub[i-1] - RC5_QW32;
}
int i, j;
unsigned long x, y;
i = j = x = y = 0;
for(int k = 0; k <=78; k++)
{
m_bufSub[i] = rotate_left((m_bufSub[i] + x + y), 3);
x = m_bufSub[i];
i = (i + 1) % 0x1开发者_开发技巧A;
m_bufKey[j] = rotate_left((m_bufKey[j] + x + y), (x + y));
y = m_bufKey[j];
j = (j + 1) % 4;
}
}
void CRc5::Rc5Encrypt(void* buf, int nLen8)
{
assert(nLen8 % 8 == 0);
nLen8 = (nLen8/8) * 8;
if(nLen8 <= 0)
return;
unsigned long* bufData = (unsigned long*)buf;
for(int k = 0; k < nLen8/8; k++)
{
unsigned long a = bufData[2*k];
unsigned long b = bufData[2*k + 1];
unsigned long le = a + m_bufSub[0];
unsigned long re = b + m_bufSub[1];
for(int i = 1; i <= 12; i++)
{
le = rotate_left((le ^ re), re) + m_bufSub[2*i];
re = rotate_left((re ^ le), le) + m_bufSub[2*i + 1];
}
bufData[2*k] = le;
bufData[2*k + 1] = re;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
void CRc5::Rc5Decrypt(void* buf, int nLen8)
{
assert(nLen8 % 8 == 0);
nLen8 = (nLen8/8) * 8;
if(nLen8 <= 0)
return;
unsigned long* bufData = (unsigned long*)buf;
for(int k = 0; k < nLen8/8; k++)
{
unsigned long ld = bufData[2*k];
unsigned long rd = bufData[2*k + 1];
for(int i = 12; i >= 1; i--)
{
rd = rotate_right((rd - m_bufSub[2*i + 1]), ld) ^ ld;
ld = rotate_right((ld - m_bufSub[2*i]), rd) ^ rd;
}
unsigned long b = rd - m_bufSub[1];
unsigned long a = ld - m_bufSub[0];
bufData[2*k] = a;
bufData[2*k + 1] = b;
}
}
unsigned long rotate_left(unsigned long nData, unsigned long nCount)
{
return (nData << (nCount & 0x1F) | nData >> 0x20 - (nCount & 0x1F));
}
////////////////////////////////////////////////////////////////////////////////////////////////
unsigned long rotate_right(unsigned long nData, unsigned long nCount)
{
return (nData << (nCount & 0x1F) | nData >> 0x20 - (nCount & 0x1F));
}
main.cpp
//all the stuff
char buf[4000];
char acc[16];
char psw[16];
recv(sConnect,buf,sizeof(buf),0);
//dec.Rc5InitKey(RC5PASSWORD_KEY);
dec.Rc5Decrypt(buf,16);
cout << buf;
why did i post it here i cant decrypt the buf which i get from the client (but we dont play this game!) yes i know but am sure that am doing something wrong inside the code so maybe someone was dealing with RC5 knows what am doing wrong , if not it's okey . thnx
Without having looked at your code in detail, I would imagine that you need to set up the key schedule before you can actually decrypt the buffer you've received.
Looks like rotate_left and rotate_right are the same, but they shouldn't be:
unsigned long rotate_left(unsigned long nData, unsigned long nCount) {
return (nData << (nCount & 0x1F) | nData >> 0x20 - (nCount & 0x1F));
}
unsigned long rotate_right(unsigned long nData, unsigned long nCount) {
return (nData << (nCount & 0x1F) | nData >> 0x20 - (nCount & 0x1F));
}
rotate_right
should be:
unsigned long rotate_right(unsigned long nData, unsigned long nCount)
{
return (nData >> (nCount & 0x1F) | nData << 0x20 - (nCount & 0x1F));
}
精彩评论