2025-06-21 14:32:54 +03:00

4.1 KiB
Raw Permalink Blame History

BS-Dec-Key: Client Analysis and Implementation

This document provides a detailed technical breakdown of the connection process for a modified Project Colette V53 server that uses the cryptographic scheme from BSL-V53. It dissects the final, working version of the handshake, packet structure, and message exchange logic.

[*] Core Concepts

The data exchange protocol is a custom protocol over TCP. The encryption is built on the NaCl library and uses a mixed, non-standard scheme.

  • Asymmetric Encryption: Curve25519 for computing a shared secret via Elliptic-curve DiffieHellman (ECDH).
  • Symmetric Encryption: XSalsa20-Poly1305 for encrypting messages after the shared secret is computed.
  • Packet Order: Unlike many protocols, the order here is not ClientHello -> ServerHello -> LoginMessage, but rather ClientHello -> LoginMessage -> ServerHello -> LoginOk.

[!] Step-by-Step Breakdown of the Connection Process

The process from initiation to a fully established encrypted session involves the exchange of four key packets in a specific order.


Step 1: ClientHello (ID: 10100)

  • Direction: Client -> Server
  • Encryption: None

This is the very first packet the client sends after establishing a TCP connection. Its structure is critically important and must exactly match the server's expectations (six integer fields and an empty string), otherwise the server will simply drop the connection.


Step 2: LoginMessage (ID: 10101)

  • Direction: Client -> Server
  • Encryption: Symmetric (SecretBox), but with a key derived asymmetrically.

This is the key and most complex packet, which is sent before receiving ServerHello.

Client-Side Preparation (Before Sending):

  1. Key Exchange and Secret Calculation:
    • The client uses the server's static server_public_key, known from the Frida script analysis.
    • The client generates its own temporary key pair (client_public_key and client_private_key).
    • The client computes a shared secret (s) via ECDH. This s is used only for encrypting/decrypting LoginMessage and LoginOk.
  2. Payload Formation:
    • The client generates its own RNonce (24 bytes).
    • The inner data (LoginData) is constructed into a ByteStream. It includes the account ID (0-1 for new), the client version (47.365.2), and numerous device information fields, including validly formatted identifiers (UUIDs, HEX strings).
    • The payload to be encrypted is assembled as RNonce + LoginData.
  3. Encryption:
    • Key: The shared secret s calculated in step 1 is used.
    • Nonce: Calculated as hash(client_pk + server_pk).
    • Process: (RNonce + LoginData) is encrypted using SecretBox(s).encrypt(...).

Packet Structure and Transmission:

The final 10101 packet consists of:

  • Client's Public Key (32 bytes, in cleartext).
  • Encrypted Payload.

Step 3: ServerHello (ID: 20100)

  • Direction: Server -> Client
  • Encryption: None

After receiving and successfully decrypting LoginMessage, the server sends this packet in cleartext. It contains the Server Nonce (SNonce), which will be used for further communication.


Step 4: LoginOk (ID: 20104)

  • Direction: Server -> Client
  • Encryption: Symmetric (SecretBox)

This is the final confirmation from the server.

  • Key: The server uses the same shared secret s that it calculated earlier.
  • Nonce: The server calculates the nonce as hash(RNonce + client_pk + server_pk).
  • Contents: Inside the decrypted payload is the second, true session key (session_key), which will be used to encrypt all subsequent messages (after the handshake).

Successfully decrypting this packet means the account is created and the session is fully established. A connection drop by the server immediately after sending LoginOk is normal behavior for a simple test client that does not continue the conversation (e.g., by sending KeepAlive packets).