Register for your free account! | Forgot your password?

You last visited: Today at 21:10

  • Please register to post and access all features, it's quick, easy and FREE!

Advertisement



BlowFish

Discussion on BlowFish within the CO2 Private Server forum part of the Conquer Online 2 category.

Reply
 
Old   #1
 
Mr_PoP's Avatar
 
elite*gold: 0
Join Date: Apr 2008
Posts: 759
Received Thanks: 285
BlowFish

is there anycode for Blowfish here in C++ works with the later clients?! like the one in ExodusBinaries?
Mr_PoP is offline  
Old 02/13/2011, 08:57   #2
 
elite*gold: 20
Join Date: Aug 2005
Posts: 1,734
Received Thanks: 1,000
This is a quote from my old post. It does contain some major errors, it does work but it leaks like a ol' pipe so it should only be used as reference.

Quote:

As usual this has no interest in private server section so here it goes, it's not finished yet. If you see errors / places where it could be better, post here. It's not tested but it should work unless there's a major fuck-up somewhere.

Blowfish.h

PHP Code:
#pragma once

#include <openssl/blowfish.h>
#pragma comment(lib, "libeay32.lib")

class CBlowfish
{
private:
    
unsigned char *DecryptIV;
    
unsigned char *EncryptIV;

    
int DecryptCounter;
    
int EncryptCounter;

    
BF_KEY *Key;
public:
    
CBlowfish(unsigned char *Dataint Length);
    ~
CBlowfish(void);

    
unsigned charEncrypt(unsigned char *Dataint Length);
    
unsigned charDecrypt(unsigned char *Dataint Length);

    
void SetKey(unsigned char *Dataint Length);
    
void SetIVs(unsigned char *DecryptIVunsigned char *EncryptIV);
}; 
Blowfish.cpp

PHP Code:
#include "StdAfx.h"
#include "Blowfish.h"

CBlowfish::CBlowfish(unsigned char *Dataint Length)
{
    
DecryptIV = new unsigned char[8];
    
EncryptIV = new unsigned char[8];
    
DecryptCounter 0;
    
EncryptCounter 0;

    
Key = new BF_KEY();
    
BF_set_key(KeyLengthData);
}

CBlowfish::~CBlowfish(void)
{
    
delete[] DecryptIV;
    
delete[] EncryptIV;
    
delete[] Key;
}

unsigned charCBlowfish::Encrypt(unsigned char *Dataint Length)
{
    
unsigned charOut = new unsigned char[Length];
    
BF_cfb64_encrypt(DataOutLengthKeyEncryptIV, &EncryptCounter1);
    return 
Out;
}
unsigned charCBlowfish::Decrypt(unsigned char *Dataint Length)
{
    
unsigned charOut = new unsigned char[Length];
    
BF_cfb64_encrypt(DataOutLengthKeyDecryptIV, &DecryptCounter0);
    return 
Out;
}
void CBlowfish::SetKey(unsigned char *Dataint Length)
{
    
BF_set_key(KeyLengthData);
    
DecryptCounter 0;
    
EncryptCounter 0;
}
void CBlowfish::SetIVs(unsigned char *DecryptIVunsigned char *EncryptIV)
{
    
memcpy(this->DecryptIVDecryptIV8);
    
memcpy(this->EncryptIVEncryptIV8);

DH.h

PHP Code:
#pragma once

#include <openssl/dh.h>
#include <openssl/bn.h>
class CDH
{
private:
    
DH *dh;
public:
    
CDH(BIGNUM *PBIGNUM *G);
    ~
CDH(void);

    
unsigned charComputeKey(BIGNUM *PublicKey);
    
void GenerateKeys();


    
void SetG(BIGNUM *G);
    
void SetP(BIGNUM *P);
    
void SetPrivate(BIGNUM *PrivateKey);
    
void SetPublic(BIGNUM *PublicKey);

    
BIGNUMGetG();
    
BIGNUMGetP();
    
BIGNUMGetPrivate();
    
BIGNUMGetPublic();

    
__declspec(property(get GetGput SetG)) BIGNUM *G;
    
__declspec(property(get GetPput SetP)) BIGNUM *P;

    
__declspec(property(get GetPrivateput SetPrivate)) BIGNUM *PrivateKey;
    
__declspec(property(get GetPublicput SetPublic)) BIGNUM *PublicKey;
}; 
DH.cpp

PHP Code:
#include "StdAfx.h"
#include "DH.h"

CDH::CDH(BIGNUM *PBIGNUM *G)
{
    
dh DH_new();
    
dh->BN_dup(P);
    
dh->BN_dup(G);
}

unsigned charCDH::ComputeKey(BIGNUM *PublicKey)
{
    
unsigned char *Key = new unsigned char[DH_size(dh)];
    
DH_compute_key(KeyPublicKeydh);
    return 
Key;
}
void CDH::GenerateKeys() 
{
    
DH_generate_key(dh);
}

void CDH::SetG(BIGNUM *G)
{
    
dh->BN_dup(G);
}

void CDH::SetP(BIGNUM *P)
{
    
dh->BN_dup(P);
}
void CDH::SetPrivate(BIGNUMPrivateKey)
{
    
dh->priv_key BN_dup(PrivateKey);
}
void CDH::SetPublic(BIGNUMPublicKey)
{
    
dh->pub_key BN_dup(PublicKey);
}
BIGNUMCDH::GetP()
{
    return 
dh->p;
}
BIGNUMCDH::GetG()
{
    return 
dh->g;
}
BIGNUMCDH::GetPrivate()
{
    return 
dh->priv_key;
}
BIGNUMCDH::GetPublic()
{
    return 
dh->pub_key;
}

CDH::~CDH(void)
{
    
delete[] dh;

Quote:
GameCryptography.h
PHP Code:
#pragma once

#include "Blowfish.h"
class CGameCryptography
{
public:
    
CGameCryptography(void);
    ~
CGameCryptography(void);

    
CBlowfish *bf;    

    
unsigned charEncrypt(unsigned char *Packetint Length);
    
unsigned charDecrypt(unsigned char *Packetint Length);
}; 
GameCryptography.cpp
PHP Code:
#include "StdAfx.h"
#include "GameCryptography.h"

CGameCryptography::CGameCryptography(void)
{
    
char *szInitialKey "DR654dt34trg4UI6";
    
bf = new CBlowfish(reinterpret_cast<unsigned char*>(szInitialKey), 16);
    
/*char *szInitialKey = "DR654dt34trg4UI6";
    unsigned char *Key = new unsigned char[sizeof(szInitialKey)];
    for(int i = 0; i < sizeof(szInitialKey); i++)
        Key[i] = (unsigned char)szInitialKey[i];
    bf = new CBlowfish(Key, 16);
    reinterpret_cast<*/
}

CGameCryptography::~CGameCryptography(void)
{
    
delete[] bf;
}
unsigned char *CGameCryptography::Encrypt(unsigned char *Packetint Length)
{
    return 
bf->Encrypt(PacketLength);
}
unsigned char *CGameCryptography::Decrypt(unsigned char *Packetint Length)
{
    return 
bf->Decrypt(PacketLength);


Handshake.h

PHP Code:
#pragma once

#include "PacketReader.h"

class Handshake
{
public:
    
Handshake(void) { }
    ~
Handshake(void) { }

    
unsigned char *ServerIV, *ClientIV;
    
char *P, *G, *PublicKey;
    
void Process(unsigned char *Packet
    {
        
PacketReader *Reader = new PacketReader(Packetsizeof(Packet), 15);
        
Reader->Advance(Reader->ReadDWord());
        
ServerIV Reader->ReadBytes(Reader->ReadDWord());
        
ClientIV Reader->ReadBytes(Reader->ReadDWord());
        
Reader->ReadString(Reader->ReadDWord());
        
Reader->ReadString(Reader->ReadDWord());
        
PublicKey Reader->ReadString(Reader->ReadDWord());
    }
}; 
HandshakeReply.h
PHP Code:
#pragma once

#include "PacketReader.h"

class HandshakeReply
{
public:
    
HandshakeReply(void) { }
    ~
HandshakeReply(void) { }

    
char *PublicKey;
    
void Process(unsigned char *Packet
    {
        
PacketReader *Reader = new PacketReader(Packetsizeof(Packet), 11);
        
Reader->Advance(Reader->ReadDWord());
        
PublicKey Reader->ReadString(Reader->ReadDWord());
    }
}; 
PacketReader.h
PHP Code:
#pragma once

class PacketReader
{
private:
    
unsigned char *Packet;


public:    
    
unsigned long Index;
    
PacketReader(unsigned char *Packetint Lengthint Position 0)
    {
        
this->Packet Packet;
        
this->Index Position;
    }
    
void Advance(unsigned long Length)
    {
        
Index += Length;
    }
    
unsigned long ReadDWord()
    {
        
unsigned long Value = *((unsigned long*)(Packet Index));
        
Index += 4;
        return 
Value;
    }
    
unsigned charReadBytes(unsigned long Length)
    {
        
unsigned char *Value = new unsigned char[Length];
        
memcpy(Value, (Packet Index), Length);
        
Index += Length;
        return 
Value;
    }
    
char *ReadString(unsigned long Length)
    {
        
charValue = new char[Length];
        for(
int i 0Lengthi++)
            
Value[i] = (char)Packet[Index i];
        
Index += Length;
        
Value[Length] = 0x00;
        return 
Value;
    }
    ~
PacketReader(void)
    {
        
delete[] Packet;
    }
}; 


EDIT: Might have found a fixed version --> attachment
Attached Files
File Type: rar ConquerCrypto.rar (3.4 KB, 45 views)
tanelipe is offline  
Thanks
3 Users
Old 02/13/2011, 18:55   #3
 
Mr_PoP's Avatar
 
elite*gold: 0
Join Date: Apr 2008
Posts: 759
Received Thanks: 285
Thanks for your help but am facing a prob can u take a look and tell me what am doing wrong?

Code:
       GameCipher test("DR654dt34trg4UI6");
	for(;;)
	{
		if((sConnect=accept(sListen,(SOCKADDR*)&addr,&addrlen)) != INVALID_SOCKET)
		{
			Print("Socket Connected -> %s",inet_ntoa(addr.sin_addr));
			char rSeed[9];
			rPassSeed(rSeed);
			char buf[1096];
			int buflen=strlen(buf);
			send(sListen,rSeed,8,0);
			recv(sListen,buf,buflen,0);
			test.Decrypt((unsigned char *)buf,(unsigned char *)buf,buflen);
			cout << buf;
		}
Result:

thanks i appreciate ur help
Mr_PoP is offline  
Old 02/13/2011, 19:47   #4
 
unknownone's Avatar
 
elite*gold: 20
Join Date: Jun 2005
Posts: 1,013
Received Thanks: 381
You can't just ouput a binary stream like that. You need to convert it to hexidecimal to be readable at all.

Code:
#include <iostream>
#include <iomanip>

void output_hex (std::ostream& out, uint8_t const* const buf, int len) {
    for (int i=0;i<len;i++)
        out << std::noshowbase
            << std::hex
            << std::setfill ('0')
            << std::setw (2)
            << static_cast<int> (buf[i])
            << " ";
}

//
output_hex (cout, buf, buflen);
unknownone is offline  
Old 02/13/2011, 19:56   #5
 
Mr_PoP's Avatar
 
elite*gold: 0
Join Date: Apr 2008
Posts: 759
Received Thanks: 285
Quote:
Originally Posted by unknownone View Post
You can't just ouput a binary stream like that. You need to convert it to hexidecimal to be readable at all.

Code:
#include <iostream>
#include <iomanip>

void output_hex (std::ostream& out, uint8_t const* const buf, int len) {
    for (int i=0;i<len;i++)
        out << std::noshowbase
            << std::hex
            << std::setfill ('0')
            << std::setw (2)
            << static_cast<int> (buf[i])
            << " ";
}

//
output_hex (cout, buf, buflen);
but am trying to decrypt what am geting from the client using Blowfish when i used the function u showed me here is the reslut:
Mr_PoP is offline  
Old 02/13/2011, 20:02   #6
 
unknownone's Avatar
 
elite*gold: 20
Join Date: Jun 2005
Posts: 1,013
Received Thanks: 381
Are you expecting to read plain text? Because that won't happen. The protocol is a binary one, and has very little text in it. For starters, fix this:

Get the result from recv(), which is the actual number of bytes receive (rather than the size of the buffer). Then output_hex (cout, buf, recv_len); You should get something a bit more readable.
unknownone is offline  
Old 02/13/2011, 20:21   #7
 
Mr_PoP's Avatar
 
elite*gold: 0
Join Date: Apr 2008
Posts: 759
Received Thanks: 285
Quote:
Originally Posted by unknownone View Post
Are you expecting to read plain text? Because that won't happen. The protocol is a binary one, and has very little text in it. For starters, fix this:

Get the result from recv(), which is the actual number of bytes receive (rather than the size of the buffer). Then output_hex (cout, buf, recv_len); You should get something a bit more readable.
so lets make every thing clear i send to the client:
Code:
const int Seed=74185296;
send(sListen,(char *)Seed,8,0);
i recv() what ever i will recv. then i take the buf into the Blowfish then it should decrypt every thing but the password right1?
Mr_PoP is offline  
Old 02/13/2011, 20:27   #8
 
unknownone's Avatar
 
elite*gold: 20
Join Date: Jun 2005
Posts: 1,013
Received Thanks: 381
You don't simple send the Seed value like that. You must structure it into the packet you posted in the other thread.

Code:
typedef struct packetSeed
{
    unsigned short Length; // 0x8
    unsigned short Type; // 0x423
    unsigned int Seed; // random
} * PPACKETSEED;

packetSeed * packet = new packetSeed();
packet->length = 8;
packet->type = 0x423;
packet->Seed = 74185296;
send(s, (uint8_t*)packet, sizeof(packetSeed), 0);
delete packet;
Oh, and I noticed you're sending/recieving on your listen socket. You shouldn't do that. You should be send/receiving on the connected socket that was returned in the call to accept(); I'd suggest go reading Beej's guide to network programming for further details.
unknownone is offline  
Old 02/13/2011, 20:32   #9
 
Mr_PoP's Avatar
 
elite*gold: 0
Join Date: Apr 2008
Posts: 759
Received Thanks: 285
Quote:
Originally Posted by unknownone View Post
You don't simple send the Seed value like that. You must structure it into the packet you posted in the other thread.

Code:
typedef struct packetSeed
{
    unsigned short Length; // 0x8
    unsigned short Type; // 0x423
    unsigned int Seed; // random
} * PPACKETSEED;

packetSeed * packet = new packetSeed();
packet->length = 8;
packet->type = 0x423;
packet->Seed = 74185296;
send(s, (uint8_t*)packet, sizeof(packetSeed), 0);
delete packet;
Oh, and I noticed you're sending/recieving on your listen socket. You shouldn't do that. You should be send/receiving on the connected socket that was returned in the call to accept(); I'd suggest go reading Beej's guide to network programming for further details.
a question if i may why should i send it by this way?

Edit: reading the Beej's guide also when i used sConnect to send and recv the cllient crashs!?
Mr_PoP is offline  
Old 02/13/2011, 20:45   #10
 
unknownone's Avatar
 
elite*gold: 20
Join Date: Jun 2005
Posts: 1,013
Received Thanks: 381
Because that's what the client expects to receive. The particular pieces of data are required in order to the client to be able to interpret the data you are sending.

For starters, the length field of the packet is required in TCP (stream based) communication, because the client must be able to recognise where a particular piece of information starts and ends. If you call send 5 times on a server, that doesn't necessarily mean that the client will need to call recv 5 times to recv those 5 pieces of data. It may only need to call it once, or it may need to call it 10 times. It depends on the load on the network, it cannot be decided beforehand where each send was sent in the stream. So we add a length to each "send" so that the receiver can interpret the data and decide where each piece of sent information begins and ends.

As for the type - This is a primitive that decides what the receiver should do with the data. There's lots of different pieces of data you can send that do different functions (for example, one might contain login information, another might contain some chat information). The type primitive just identifies each piece of information so that it can be mapped to a function that is to be performed on the payload. (In this case, is the seed).

So if you send data as described. The client will first read the length, to determine when to stop receiving for this particular piece of data. It will then read the type, and see it is the Seed packet type, and it can then call a function which sets the seed for the cryptography using the final piece of data in the stream.
unknownone is offline  
Thanks
1 User
Old 02/13/2011, 20:53   #11
 
Mr_PoP's Avatar
 
elite*gold: 0
Join Date: Apr 2008
Posts: 759
Received Thanks: 285
Quote:
Originally Posted by unknownone View Post
Because that's what the client expects to receive. The particular pieces of data are required in order to the client to be able to interpret the data you are sending.

For starters, the length field of the packet is required in TCP (stream based) communication, because the client must be able to recognise where a particular piece of information starts and ends. If you call send 5 times on a server, that doesn't necessarily mean that the client will need to call recv 5 times to recv those 5 pieces of data. It may only need to call it once, or it may need to call it 10 times. It depends on the load on the network, it cannot be decided beforehand where each send was sent in the stream. So we add a length to each "send" so that the receiver can interpret the data and decide where each piece of sent information begins and ends.

As for the type - This is a primitive that decides what the receiver should do with the data. There's lots of different pieces of data you can send that do different functions (for example, one might contain login information, another might contain some chat information). The type primitive just identifies each piece of information so that it can be mapped to a function that is to be performed on the payload. (In this case, is the seed).

So if you send data as described. The client will first read the length, to determine when to stop receiving for this particular piece of data. It will then read the type, and see it is the Seed packet type, and it can then call a function which sets the seed for the cryptography using the final piece of data in the stream.
man thanks u made my day xD , really thnx , onther question :P why is the client crashs when i use sConnect?
Mr_PoP is offline  
Old 02/13/2011, 20:55   #12
 
unknownone's Avatar
 
elite*gold: 20
Join Date: Jun 2005
Posts: 1,013
Received Thanks: 381
Most likely because you are sending incorrectly formed data which the client doesn't expect, and it is unable to recover from the error, so it just shuts down.
unknownone is offline  
Old 02/13/2011, 21:01   #13
 
Mr_PoP's Avatar
 
elite*gold: 0
Join Date: Apr 2008
Posts: 759
Received Thanks: 285
Quote:
Originally Posted by unknownone View Post
Most likely because you are sending incorrectly formed data which the client doesn't expect, and it is unable to recover from the error, so it just shuts down.
i did the same thing u told me :-s

Code:
packetSeed * packet = new packetSeed();
			packet->Length = 8;
			packet->Type = 0x423;
			packet->Seed = 74185296;
			send(sConnect, (char*)packet, sizeof(packetSeed), 0);
ummmmm....
Mr_PoP is offline  
Old 02/13/2011, 21:08   #14
 
unknownone's Avatar
 
elite*gold: 20
Join Date: Jun 2005
Posts: 1,013
Received Thanks: 381
Difficult for me to determine with so little information. Firstlt, try checking the data is correctly formed by printing it out as a stream.

output_hex(cout, (char*)packet, packet->length);

It should look something like

08 00 23 04 50 FA 6B 04

You need to encrypt it before sending though.
unknownone is offline  
Old 02/14/2011, 03:05   #15
 
QuickCo's Avatar
 
elite*gold: 0
Join Date: Jan 2010
Posts: 139
Received Thanks: 45
Maybe because he's using 127.0.0.1, the client reject Localhost.
QuickCo is offline  
Reply


Similar Threads Similar Threads
Getting blowfish key and using the algorithm
03/17/2011 - SRO Coding Corner - 10 Replies
Good evening:) I am still busy with the packets of silkroad and I'm now trying to understand on how to decrypt the packets but I'm having some problems with it. I read drew benton's artikel about the silkroad security but I still don't know on which blowfish key is used to decrypt the packets. let's say these four packets are the first 4 S -> C 00000 25 00 00 50 00 00 0e d2 a9 27 80 2d c3 23 6c f6 %..P.....'.-.#l. 00016 00 00 00 62 00 00 00 8d ac fe 38 3d d0 9c ef 67 ...
[help]blowfish
10/15/2009 - Lineage 2 - 0 Replies
hello i haven't idea how to find blowfish in server any idea?



All times are GMT +2. The time now is 21:10.


Powered by vBulletin®
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Terms of Service | Abuse
Copyright ©2024 elitepvpers All Rights Reserved.