Register for your free account! | Forgot your password?

Go Back   elitepvpers > MMORPGs > Conquer Online 2 > CO2 Private Server
You last visited: Today at 17:37

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

Advertisement



Upgrading password encryption

Discussion on Upgrading password encryption within the CO2 Private Server forum part of the Conquer Online 2 category.

Reply
 
Old   #1

 
Kiyono's Avatar
 
elite*gold: 20
Join Date: Jun 2006
Posts: 3,296
Received Thanks: 925
Upgrading password encryption

Might as well post it here. I'm trying to upgrade the password encryption from Hybrid's 5135 source to be used with a 5250 client but it's kinda giving me a headache.
Well I'm confused.

Some information:
Password handling:
The original decrypting code:
Kinshi's proxy and Immune's source decrypting code:
What I got after trying to convert their decrypting code:

So can I get some help with the password decrypting code?
//edit I guess the title should be decryption... oh well.
Kiyono is offline  
Old 01/10/2011, 23:59   #2
 
elite*gold: 21
Join Date: Jul 2005
Posts: 9,193
Received Thanks: 5,380
Here's from my source using same kinda system.

byte[] Password = read from the packet.

Code:
string Pass;
            msvcrt.msvcrt.srand(Client.PassSeed);
            var rc5Key = new byte[0x10];
            for (int i = 0; i < 0x10; i++)
                rc5Key[i] = (byte)msvcrt.msvcrt.rand();
            ConquerPasswordCryptpographer A = new ConquerPasswordCryptpographer(User);
            Encryption.RC5 B = new Encryption.RC5(rc5Key);
            Pass = Encoding.ASCII.GetString(
                  (new ConquerPasswordCryptpographer(User).Decrypt(new Encryption.RC5(rc5Key).Decrypt(Password))));
            Pass = Pass.Replace("\0", "");
I just use the released liberate cryptography dll, msvcrt dll and then the following pass crypt class.

Code:
 public sealed class RC5Exception : Exception
    {
        public RC5Exception(string message) : base(message) { }
    }

    public sealed class RC5
    {
        private readonly uint[] _bufKey = new uint[4];
        private readonly uint[] _bufSub = new uint[26];

        public RC5(byte[] data)
        {
            if (data.Length != 16) throw new RC5Exception("Invalid data length. Must be 16 bytes");
            const uint p32 = 0xB7E15163;
            const uint q32 = 0x61C88647;
            uint offsetA = 0, offsetB = 0, A = 0, B = 0;
            for (int i = 0; i < 4; i++)
                _bufKey[i] = (uint)(data[i * 4] + (data[i * 4 + 1] << 8) + (data[i * 4 + 2] << 16) + (data[i * 4 + 3] << 24));
            _bufSub[0] = p32;
            for (int i = 1; i < 26; i++)
            {
                _bufSub[i] = _bufSub[i - 1] - q32;
            }
            for (int s = 1; s <= 78; s++)
            {
                _bufSub[offsetA] = LeftRotate(_bufSub[offsetA] + A + B, 3);
                A = _bufSub[offsetA];
                offsetA = (offsetA + 1) % 0x1A;
                _bufKey[offsetB] = LeftRotate(_bufKey[offsetB] + A + B, (int)(A + B));
                B = _bufKey[offsetB];
                offsetB = (offsetB + 1) % 4;
            }
        }
        public byte[] Decrypt(byte[] data)
        {
            if (data.Length % 8 != 0) throw new RC5Exception("Invalid password length. Must be multiple of 8");
            int nLen = data.Length / 8 * 8;
            if (nLen <= 0) throw new RC5Exception("Invalid password length. Must be greater than 0 bytes.");
            uint[] bufData = new uint[data.Length / 4];
            for (int i = 0; i < data.Length / 4; i++)
                bufData[i] = (uint)(data[i * 4] + (data[i * 4 + 1] << 8) + (data[i * 4 + 2] << 16) + (data[i * 4 + 3] << 24));
            for (int i = 0; i < nLen / 8; i++)
            {
                uint ld = bufData[2 * i];
                uint rd = bufData[2 * i + 1];
                for (int j = 12; j >= 1; j--)
                {
                    rd = RightRotate((rd - _bufSub[2 * j + 1]), (int)ld) ^ ld;
                    ld = RightRotate((ld - _bufSub[2 * j]), (int)rd) ^ rd;
                }
                uint B = rd - _bufSub[1];
                uint A = ld - _bufSub[0];
                bufData[2 * i] = A;
                bufData[2 * i + 1] = B;
            }
            byte[] result = new byte[bufData.Length * 4];
            for (int i = 0; i < bufData.Length; i++)
            {
                result[i * 4] = (byte)bufData[i];
                result[i * 4 + 1] = (byte)(bufData[i] >> 8);
                result[i * 4 + 2] = (byte)(bufData[i] >> 16);
                result[i * 4 + 3] = (byte)(bufData[i] >> 24);
            }
            return result;
        }

        public byte[] Encrypt(byte[] data)
        {
            if (data.Length % 8 != 0) throw new RC5Exception("Invalid password length. Must be multiple of 8");
            int nLen = data.Length / 8 * 8;
            if (nLen <= 0) throw new RC5Exception("Invalid password length. Must be greater than 0 bytes.");
            uint[] bufData = new uint[data.Length / 4];
            for (int i = 0; i < data.Length / 4; i++)
                bufData[i] = (uint)(data[i * 4] + (data[i * 4 + 1] << 8) + (data[i * 4 + 2] << 16) + (data[i * 4 + 3] << 24));
            for (int i = 0; i < nLen / 8; i++)
            {
                uint A = bufData[i * 2];
                uint B = bufData[i * 2 + 1];
                uint le = A + _bufSub[0];
                uint re = B + _bufSub[1];
                for (int j = 1; j <= 12; j++)
                {
                    le = LeftRotate((le ^ re), (int)re) + _bufSub[j * 2];
                    re = LeftRotate((re ^ le), (int)le) + _bufSub[j * 2 + 1];
                }
                bufData[i * 2] = le;
                bufData[i * 2 + 1] = re;
            }
            byte[] result = new byte[bufData.Length * 4];
            for (int i = 0; i < bufData.Length; i++)
            {
                result[i * 4] = (byte)bufData[i];
                result[i * 4 + 1] = (byte)(bufData[i] >> 8);
                result[i * 4 + 2] = (byte)(bufData[i] >> 16);
                result[i * 4 + 3] = (byte)(bufData[i] >> 24);
            }
            return result;
        }

        internal static uint LeftRotate(uint dwVar, int dwOffset)
        {
            return (dwVar << (dwOffset & 0x1F) | dwVar >> 0x20 - (dwOffset & 0x1F));
        }

        internal static uint RightRotate(uint dwVar, int dwOffset)
        {
            return (dwVar >> (dwOffset & 0x1F) | dwVar << 0x20 - (dwOffset & 0x1F));
        }
    }
pro4never is offline  
Thanks
1 User
Old 01/11/2011, 00:05   #3
 
elite*gold: 0
Join Date: Jun 2009
Posts: 787
Received Thanks: 314
Buffer.BlockCopy is a .NET method
_tao4229_ is offline  
Thanks
1 User
Old 01/11/2011, 06:27   #4
 
.Kinshi's Avatar
 
elite*gold: 0
Join Date: Dec 2010
Posts: 341
Received Thanks: 255
System.Buffer.BlockCopy(..);
.Kinshi is offline  
Old 01/11/2011, 17:35   #5

 
Kiyono's Avatar
 
elite*gold: 20
Join Date: Jun 2006
Posts: 3,296
Received Thanks: 925
Quote:
Originally Posted by pro4never View Post
Here's from my source using same kinda system.

byte[] Password = read from the packet.
Spoiler to make it smaller.
The thing is that I don't know how to read from the packet in fact that is the only problem I have.
//edit Incase you need it:

1086/0x43E packet handling:
1086/0x43E packet:
Kiyono is offline  
Old 01/11/2011, 19:35   #6
 
elite*gold: 21
Join Date: Jul 2005
Posts: 9,193
Received Thanks: 5,380
Well you have a few options..

#1: use buffer block copy to copy from the destination array into a new one.

#2: use a packet reading method from some other source or write your own...

Here's the readbytes method tannel made that iirc is what I used in my proxy.

Code:
 public byte[] ReadBytes(int Count)
        {
            byte[] Val = new byte[Count];
            Buffer.BlockCopy(PData, Position, Val, 0, Count);
            Position += Count;
            return Val;
        }
Therefor you just readbytes the password section of the login packet and run that through the method.

Very simple really... just find the password offset in the packet and you're good to go.


<edit>

taking a glance at your password thing you are trying to read it as a string... that's not what you want to do.

What you need to be doing is reading the bytes of the password into an array, decrypting that array using password crypt and saving the output into a password string.
pro4never is offline  
Old 01/11/2011, 20:04   #7

 
Kiyono's Avatar
 
elite*gold: 20
Join Date: Jun 2006
Posts: 3,296
Received Thanks: 925
Quote:
Originally Posted by pro4never View Post
Well you have a few options..

#1: use buffer block copy to copy from the destination array into a new one.

#2: use a packet reading method from some other source or write your own...

Here's the readbytes method tannel made that iirc is what I used in my proxy.

Code:
 public byte[] ReadBytes(int Count)
        {
            byte[] Val = new byte[Count];
            Buffer.BlockCopy(PData, Position, Val, 0, Count);
            Position += Count;
            return Val;
        }
Therefor you just readbytes the password section of the login packet and run that through the method.

Very simple really... just find the password offset in the packet and you're good to go.


<edit>

taking a glance at your password thing you are trying to read it as a string... that's not what you want to do.

What you need to be doing is reading the bytes of the password into an array, decrypting that array using password crypt and saving the output into a password string.
Well about Buffer.BlockCopy, I started but I simply couldn't find what had to be the first value (called Array src or in your case PData) which kinda had me confused.
Kiyono is offline  
Old 01/11/2011, 20:11   #8
 
elite*gold: 0
Join Date: Sep 2008
Posts: 1,683
Received Thanks: 506
Quote:
Originally Posted by Kiyono View Post
Well about Buffer.BlockCopy, I started but I simply couldn't find what had to be the first value (called Array src or in your case PData) which kinda had me confused.
Array Source perhaps?
Seriously, how can that not be the easiest thing to understand?
Basser is offline  
Old 01/11/2011, 20:30   #9

 
Kiyono's Avatar
 
elite*gold: 20
Join Date: Jun 2006
Posts: 3,296
Received Thanks: 925
Quote:
Originally Posted by Basser View Post
Array Source perhaps?
Seriously, how can that not be the easiest thing to understand?
You misread? I wasn't asking what Array src meant.
Kiyono is offline  
Old 01/11/2011, 21:39   #10
 
elite*gold: 0
Join Date: Sep 2008
Posts: 1,683
Received Thanks: 506
Quote:
Originally Posted by Kiyono View Post
You misread? I wasn't asking what Array src meant.
Than what was your asking? Looks like your saying you didn't know what the first parameter is..
Basser is offline  
Old 01/11/2011, 21:52   #11
 
elite*gold: 21
Join Date: Jul 2005
Posts: 9,193
Received Thanks: 5,380
Buffer block copy works as follows iirc

(Source array (copy from main packet), Source offset(where to start reading from the main packet), Destination Array (where you are copying to. The password array), Destination Offset (where to start writing in destination packet), Count (how many bytes to copy over))
pro4never is offline  
Old 01/11/2011, 22:22   #12

 
Kiyono's Avatar
 
elite*gold: 20
Join Date: Jun 2006
Posts: 3,296
Received Thanks: 925
Am I that bad in English?
I know how BlockCopy works...
Anyway I got something but it doesn't work >_>

1086/0x43E structure:
1086/0x43E handler:

My decrypting:

This should work but it's still giving me invalid password and it's not my seed being wrong either.
Kiyono is offline  
Old 01/12/2011, 01:48   #13
 
elite*gold: 21
Join Date: Jul 2005
Posts: 9,193
Received Thanks: 5,380
Quote:
Originally Posted by Kiyono View Post
The thing is that I don't know how to read from the packet in fact that is the only problem I have.
//edit Incase you need it:


You say you don't know how to copy from the packet... I just said you make a array to store the password and then block copy to copy the relevant bytes into it and then run the password array through the decryption method to return a string.

Your problem is that at least in the first code you posted it appears as though you are using pointers to read the bytes and make them into a string format.

Keep in mind it's 16 bytes just like every single other non counted string in conquer lol.
pro4never is offline  
Old 01/12/2011, 09:57   #14
 
elite*gold: 20
Join Date: Jul 2007
Posts: 613
Received Thanks: 486
i think the problem is with the szUser , the value u should receive for it is only 16 bytes starting from offset 4
samehvan is offline  
Old 01/12/2011, 17:12   #15

 
Kiyono's Avatar
 
elite*gold: 20
Join Date: Jun 2006
Posts: 3,296
Received Thanks: 925
Quote:
Originally Posted by pro4never View Post
You say you don't know how to copy from the packet... I just said you make a array to store the password and then block copy to copy the relevant bytes into it and then run the password array through the decryption method to return a string.

Your problem is that at least in the first code you posted it appears as though you are using pointers to read the bytes and make them into a string format.

Keep in mind it's 16 bytes just like every single other non counted string in conquer lol.
Well I can't really do anything about the pointer usage since it's what Hybrid coded and I don't know how to change it.
Quote:
Originally Posted by samehvan View Post
i think the problem is with the szUser , the value u should receive for it is only 16 bytes starting from offset 4
No it's not the User, I printed it to the console and it showed the correct User.

//edit With:
Client.Password = Client.Decrypt(login->User, Received);
And entering password: 123456789
and the console prints: #<"%♀'$&! which are indeed 9 characters but not the correct ones.
Kiyono is offline  
Reply


Similar Threads Similar Threads
[HELP] Password encryption
12/26/2009 - CO2 Private Server - 27 Replies
What Password encryption does conquer have? i want to code register script and don`t know encryption for password,its not md5.
AuthServer password encryption
04/26/2009 - CO2 Private Server - 1 Replies
Well thought it would fit in this section. Most of the sources I seen works this way: the first time an account login, it takes the "encrypted" password received and set it in the database. I've been trying to figure the encryption used, but with no success, my ASM skills just sucks. So, could anyone decent with assembler/debugging help me with this?
CO password encryption
11/30/2008 - Conquer Online 2 - 3 Replies
Was it ever released? I know it was hiding in dev section for some time but I don't know if it ever got out. If it has, a friendly link to where to? Or if not, maybe an explanation? It's quite a weird encryption at first glance. Thanks in advance. <hr>Append on Apr 6 2007, 20:50<hr> As much as people would probably not like to help out, I'm trying to get stuff going for the benefit of the community : [ I'm doing a c++ server emu and so far everything's going smooth except the password...
Conquer Password Encryption?
12/25/2007 - Conquer Online 2 - 4 Replies
Me and my bro are currently making a private server and we need help with the password encryption. Any help would be greatly appreciated. :D



All times are GMT +1. The time now is 17:38.


Powered by vBulletin®
Copyright ©2000 - 2025, 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 ©2025 elitepvpers All Rights Reserved.