• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

Windows XTEA encryption problem

Liuciferis

We'll bang, OKAY?
Joined
Dec 4, 2009
Messages
101
Reaction score
5
Location
Lithuania
Hello,

I am writing a Java server emulator for Tibia and I having some problems with XTEA encryption.
My encyption:
Code:
    public static byte[] encrypt(byte[] bytes, long[] key) throws IOException
    {
        ByteArrayOutputStream st = new ByteArrayOutputStream();
        st.write(bytes);

        long delta = 0x61C88647;

        // the message must be a multiple of 8
        int paddingBytes = bytes.length & 7;
        if (paddingBytes != 0) {
            int count = 8 - paddingBytes;
            for (int i = 0; i < count; i++)
                st.write(0x33);
        }
      
        bytes = st.toByteArray();

        int messageLength = bytes.length / 4;
        int readPos = 0;

        while (readPos < messageLength)
        {
            long v0 = bytes[readPos], v1 = bytes[readPos + 1];
            long sum = 0;

            for (int i = 32; --i >= 0;)
            {
                v0 += ((v1 << 4 ^ v1 >> 5) + v1) ^ (sum + key[(int) (sum & 3)]);
                sum -= delta;
                v1 += ((v0 << 4 ^ v0 >> 5) + v0) ^ (sum + key[(int) ((sum >> 11) & 3)]);
            }

            bytes[readPos++] = (byte) v0;
            bytes[readPos++] = (byte) v1;
        }
        return bytes;
    }

Encryption result:
Code:
Normal:
35 0 14 E 0 31 A 48 65 6C 6C 6F 20 77 6F 72 6C 64 21 64 1 0 5 0 41 75 72 65 61 9 0 31 32 37 2E 30 2E 30 2E 31 4 1C 0 1 0 6 0 57 64 65 6D 6F 6E FF FF

Encrypted:
AB A3 92 81 FC 31 F3 F3 AF 85 C3 D7 C3 24 6F 72 6C 64 21 64 1 0 5 0 41 75 72 65 61 9 0 31 32 37 2E 30 2E 30 2E 31 4 1C 0 1 0 6 0 57 64 65 6D 6F 6E FF FF 33

As you can see, it encrypts only ~14 bytes at the beginning and that's all.

I have no idea why it works like that. Maybe someone could answer me? :p
 
Hm. What could be wrong if xtea encrypted bytes are different than original packet? :D

XTEA:
Code:
package com.network.encryption;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

public class XTEA
{
    private static final int DELTA = 0x9E3779B9; //0x61C88647;//0x9E3779B9;
    private static final int iteration = 0xC6EF3720;

    private long[] _key;

    public XTEA(long[] key) throws IllegalArgumentException
    {
        if (key.length != 4)
            throw new IllegalArgumentException();

        _key = key;
    }

    private void byte2int(byte[] bytes, int offset, int[] res)
    {
        res[0] = (int) ((((int) bytes[offset] & 0xff) << 24)
                | (((int) bytes[offset + 1] & 0xff) << 16)
                | (((int) bytes[offset + 2] & 0xff) << 8) | ((int) bytes[offset + 3] & 0xff));
        res[1] = (int) ((((int) bytes[offset + 4] & 0xff) << 24)
                | (((int) bytes[offset + 5] & 0xff) << 16)
                | (((int) bytes[offset + 6] & 0xff) << 8) | ((int) bytes[offset + 7] & 0xff));
    }

    private void int2byte(int[] i, int offset, byte[] res)
    {
        res[offset] = (byte) ((i[0] & 0xff000000) >>> 24);
        res[offset + 1] = (byte) ((i[0] & 0x00ff0000) >>> 16);
        res[offset + 2] = (byte) ((i[0] & 0x0000ff00) >>> 8);
        res[offset + 3] = (byte) (i[0] & 0x000000ff);
        res[offset + 4] = (byte) ((i[1] & 0xff000000) >>> 24);
        res[offset + 5] = (byte) ((i[1] & 0x00ff0000) >>> 16);
        res[offset + 6] = (byte) ((i[1] & 0x0000ff00) >>> 8);
        res[offset + 7] = (byte) (i[1] & 0x000000ff);
    }

    private void encipher(int[] block)
    {
        int n = 32;
        int delta_sum = 0;
        while (n-- > 0)
        {
            block[0] += ((block[1] << 4 ^ block[1] >> 5) + block[1])
                    ^ (delta_sum + _key[delta_sum & 3]);
            delta_sum += DELTA;
            block[1] += ((block[0] << 4 ^ block[0] >> 5) + block[0])
                    ^ (delta_sum + _key[delta_sum >> 11 & 3]);
        }
    }

    private void decipher(int[] e_block)
    {
        int delta_sum = iteration;
        int n = 32;
        while (n-- > 0)
        {
            e_block[1] -= ((e_block[0] << 4 ^ e_block[0] >> 5) + e_block[0])
                    ^ (delta_sum + _key[delta_sum >> 11 & 3]);
            delta_sum -= DELTA;
            e_block[0] -= ((e_block[1] << 4 ^ e_block[1] >> 5) + e_block[1])
                    ^ (delta_sum + _key[delta_sum & 3]);
        }
    }

    public byte[] encrypt(byte[] buffer) throws IOException
    {
        ByteArrayOutputStream st = new ByteArrayOutputStream();
        st.write(buffer);
       
        int paddingBytes = st.size() & 7;
        if (paddingBytes != 0)
        {
            for (int i = 0; i < 8 - paddingBytes; i++)
                st.write(0x33);
        }
       
        byte[] bb = st.toByteArray();

        int[] asInt = new int[2];
        for (int i = 0; i < bb.length; i += 8)
        {
            byte2int(bb, i, asInt);
            encipher(asInt);
            int2byte(asInt, i, bb);
        }
        return bb;
    }

    public byte[] decrypt(byte[] buffer)
    {
        int[] asInt = new int[2];
        for (int i = 0; i < buffer.length; i += 8)
        {
            byte2int(buffer, i, asInt);
            decipher(asInt);
            int2byte(asInt, i, buffer);
        }
        return buffer;
    }
}
 
Back
Top