Jump to content
/dev/not/null

Need help in fixing client connection

Recommended Posts

Hello, Mangos Community! I'm trying to developing python core from scratch and using your project as example. Currently my client stucks on 'Connected' and I think problem can be with packet encryption. Can anybody help me with debug or advice ? This is my project.

And this is how packet encrypted:

class HeaderCrypt(object):

    ENCRYPT_HEADER_SIZE = 4
    DECRYPT_HEADER_SIZE = 6

    def __init__(self, session_key):
        self.session_key = session_key
        self.send_i = 0
        self.send_j = 0
        self.recv_i = 0
        self.recv_j = 0

    def encrypt(self, data):
        assert len(data) >= HeaderCrypt.ENCRYPT_HEADER_SIZE
        encrypted_header = [0] * HeaderCrypt.ENCRYPT_HEADER_SIZE

        for index in range(HeaderCrypt.ENCRYPT_HEADER_SIZE):
            enc = (data[index] ^ self.session_key[self.send_i]) + self.send_j
            enc %= 0x100
            encrypted_header[index] = self.send_j = enc
            self.send_i = (self.send_i + 1) % len(self.session_key)

        return bytes(encrypted_header) + data[HeaderCrypt.ENCRYPT_HEADER_SIZE:]

    def decrypt(self, data):
        assert len(data) >= HeaderCrypt.DECRYPT_HEADER_SIZE
        decrypted_header = [0] * HeaderCrypt.DECRYPT_HEADER_SIZE

        for index in range(self.DECRYPT_HEADER_SIZE):
            dec = (data[index] - self.recv_j) ^ self.session_key[self.recv_i]
            dec %= 0x100
            decrypted_header[index] = dec
            self.recv_j = data[index]
            self.recv_i = (self.recv_i + 1) % len(self.session_key)

        return bytes(decrypted_header) + data[HeaderCrypt.DECRYPT_HEADER_SIZE:]

 

Edited by /dev/not/null

Share this post


Link to post
Share on other sites

Here is the relevant code from MaNGOS regarding encrypting / decrypting. Translating to Python should be trivial, and I guess you notice where is your issue.

    // encryption
    // _key = session key
    for (size_t t = 0; t < ENCRYPT_HEADER_SIZE; t++)
     {
         _send_i %= _key.size();
         uint8 x = (data[t] ^ _key[_send_i]) + _send_j;
         ++_send_i;
         data[t] = _send_j = x;
     }
    // decryption
    // _key = session key
     for (size_t t = 0; t < DECRYPT_HEADER_SIZE; t++)
     {
         _recv_i %= _key.size();
         uint8 x = (data[t] - _recv_j) ^ _key[_recv_i];
         ++_recv_i;
         _recv_j = data[t];
         data[t] = x;
     }

 

Share this post


Link to post
Share on other sites
On 12/4/2018 at 11:28 AM, H0zen said:

Here is the relevant code from MaNGOS regarding encrypting / decrypting. Translating to Python should be trivial, and I guess you notice where is your issue.

    // encryption
    // _key = session key
    for (size_t t = 0; t < ENCRYPT_HEADER_SIZE; t++)
     {
         _send_i %= _key.size();
         uint8 x = (data[t] ^ _key[_send_i]) + _send_j;
         ++_send_i;
         data[t] = _send_j = x;
     }
    // decryption
    // _key = session key
     for (size_t t = 0; t < DECRYPT_HEADER_SIZE; t++)
     {
         _recv_i %= _key.size();
         uint8 x = (data[t] - _recv_j) ^ _key[_recv_i];
         ++_recv_i;
         _recv_j = data[t];
         data[t] = x;
     }

 

Well, as I can see from the mangos code, there are also some key generating exists:

void AuthCrypt::Init(BigNumber* K)
{
    uint8* key = new uint8[SHA_DIGEST_LENGTH];
    uint8 recvSeed[SEED_KEY_SIZE] = { 0x38, 0xA7, 0x83, 0x15, 0xF8, 0x92, 0x25, 0x30, 0x71, 0x98, 0x67, 0xB1, 0x8C, 0x4, 0xE2, 0xAA };
    HMACSHA1 recvHash(SEED_KEY_SIZE, (uint8*)recvSeed);
    recvHash.UpdateBigNumber(K);
    recvHash.Finalize();
    memcpy(key, recvHash.GetDigest(), SHA_DIGEST_LENGTH);
    _key.resize(SHA_DIGEST_LENGTH);
    std::copy(key, key + SHA_DIGEST_LENGTH, _key.begin());
    delete[] key;

    _send_i = _send_j = _recv_i = _recv_j = 0;
    _initialized = true;
}

I tried to implement this in Python, but had no success:

 

    def _generate_key(self, session_key):
        key = bytes(20)
        seed = b'8\xa7\x83\x15\xf8\x92%0q\x98g\xb1\x8c\x04\xe2\xaa'
        hashed = hmac.new(seed, None, sha1)
        return hashed.digest()

Need help with hmac_sha1 python implementation.

Edited by /dev/not/null

Share this post


Link to post
Share on other sites

Solved. I just need to add code to generate key for HeaderCrypt correctly:

    def _generate_key(self, session_key):
        seed = b'8\xa7\x83\x15\xf8\x92%0q\x98g\xb1\x8c\x04\xe2\xaa'
        hashed = hmac.new(seed, session_key, sha1)
        return hashed.digest()

 

Edited by /dev/not/null
  • Like 1

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Contact Us

To contact us click here
You can also email us at [email protected]

Privacy Policy | Terms & Conditions

Repositories

The Link to the master list
of MaNGOS repositories:
Copyright © getMaNGOS. All rights Reserved.

This website is in no way associated with or endorsed by Blizzard Entertainment®
×