Skip to content

Login RSA/XTEA Envelope

The LOGIN and RECONNECT packets carry the login credentials inside a shared RSA/XTEA envelope. The same envelope is used by the signup packets; their decrypted fields are described in Init Protocol. This guide shows how to unwrap the login packet and read its decrypted fields.

Decode flow

LOGIN / RECONNECT payload
  ├─ outer login fields
  └─ 2-byte ciphertext length + RSA ciphertext
          │
          ├─ RSA private-key operation
          ▼
      0x0A + four XTEA keys + 2-byte plaintext length
          + XTEA ciphertext padded to an 8-byte boundary
          │
          ├─ XTEA decryption in 8-byte blocks
          ▼
      login payload, trimmed to its declared plaintext length
          │
          └─ parse credentials using the type chosen by INIT_LOGIN

The outer fields before the RSA block are listed in Login Protocol. The ciphertext length is a two-byte big-endian value and counts only the following RSA ciphertext bytes.

Unwrap the envelope

  1. Read the RSA ciphertext length and exactly that many bytes from the login packet.
  2. Apply RSA decryption with the matching private key: for ciphertext integer c, compute m = c^d mod n, where d is the private exponent and n is the modulus. Interpret the ciphertext as the big-endian integer representation used by the RSA client; a leading zero may be present to keep the integer positive.
  3. Read the recovered envelope in this order:
Field Size Meaning
Magic 1 byte Must be 0x0A
XTEA key 16 bytes Four 4-byte integers, in order K0, K1, K2, K3
Plaintext length 2 bytes Number of meaningful bytes after XTEA decryption
Encrypted payload Rounded up to a multiple of 8 bytes XTEA ciphertext, including block padding
  1. Decrypt the encrypted payload with XTEA using the four key integers. XTEA processes 8-byte blocks; interpret each block as two big-endian 4-byte words. The encrypted payload length is ceil(plaintext length / 8) * 8 bytes.
  2. Keep only the number of decrypted bytes specified by the plaintext length. Any bytes after that length only complete the final XTEA block.

Read the login payload

The decrypted bytes are consumed in this order:

Field Size / encoding How to interpret it
ISAAC seeds 16 bytes Four consecutive 4-byte integers, seed[0] through seed[3]
Machine ID 24 bytes Opaque machine identifier
Affiliate ID 2 bytes Unsigned big-endian integer
Credentials Depends on INIT_LOGIN See the credential encodings below
Password 14 bytes Two consecutive 7-byte base-38 values

The one-byte credential type from INIT_LOGIN determines how to parse the credentials field; it is not repeated inside the decrypted payload.

INIT_LOGIN credential type Encoding Size / decoding
1 or 2 Base-37 display name One 8-byte integer, decoded as a base-37 name
3 Email JStr2: a leading zero byte followed by a zero-terminated string

Each 7-byte password value is a big-endian integer decoded as base 38. Repeatedly divide by 38 and map remainders 2–27 to a–z, 28–37 to 0–9, and 0 or 1 to _. Decode the two values in order and join their character sequences to recover the packed password.

The nonce is formed from the low 32 bits of seed[2] followed by the low 32 bits of seed[3]. It must match the 64-bit nonce returned by the INIT_LOGIN acknowledgement.