4.1 KiB
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 Diffie–Hellman (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 ratherClientHello
->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):
- 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
andclient_private_key
). - The client computes a shared secret (
s
) via ECDH. Thiss
is used only for encrypting/decryptingLoginMessage
andLoginOk
.
- The client uses the server's static
- Payload Formation:
- The client generates its own
RNonce
(24 bytes). - The inner data (
LoginData
) is constructed into aByteStream
. 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
.
- The client generates its own
- 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 usingSecretBox(s).encrypt(...)
.
- Key: The shared secret
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).