Contents

Contents

  1. Introduction
  2. Cryptographic primitives
  3. Terminology
  4. Session establishment
  5. Message structure
  6. AES key set derivation
  7. Guarantees
  8. Contact us
01 — Introduction

The binary transport that keeps your chats safe

The japap protocol is designed to prevent third parties from accessing the plaintext messages exchanged between client and server. Even if a device's security is compromised, an intruder cannot exploit that breach to decrypt messages.

A mobile messaging protocol must keep three promises at once: encrypt every byte, hold up on an intermittent connection, and come online instantly on a phone just out of airplane mode. Here is how japap keeps all three.

The algorithms used during session establishment are RSA 2048 and AES-256. Once the session is established, every message is encrypted with AES-256-CBC under a derived key, unique for each message.

02 — Cryptographic primitives

Four primitives, zero shortcuts

japap relies exclusively on standard, published cryptographic algorithms, battle-tested by twenty years of public scrutiny. No homebrew crypto.

Diffie-Hellman
2048 bits

Lets two devices that have never spoken derive a shared secret without ever transmitting it. The key stays on your devices.

RSA
2048 bits

Protects the key exchange phase from any interception. Diffie-Hellman parameters travel only inside an RSA envelope.

AES-256
CBC mode

Encrypts every message with a uniquely derived key. Two identical messages produce two completely different ciphertexts.

Keyed MAC
SHA-1 HMAC

Authenticates every message sent. A single altered byte is enough to have the frame rejected. Impossible to forge without the key.

03 — Terminology

Six terms to know

Six terms recur throughout this document. Here are their precise definitions.

Message identifier
64 bits

Uniquely identifies each message within a session. Prevents replay attacks.

Message key
128 bits

The last 128 bits of the SHA-1 of the message to encrypt (external header excluded). Used to derive the AES key set.

Session key
2048 bits

A key shared between client and server, created during session establishment. It is never transmitted over the network.

AES key set
48 bytes

32 bytes of key and 16 bytes of initialization vector, used for AES-256-CBC. Derived per message.

External header
24 bytes

Prepended to the encrypted message. Contains the session key identifier (8 bytes) and the message key (16 bytes).

Session key identifier
64 bits

The last 64 bits of the SHA-1 of the session key. Lets the server locate the key used to encrypt a message.

04 — Session establishment

An 8-step dance

A session is created the first time the app is opened or after the user logs out. The algorithms used are RSA 2048 and AES-256. Before the session is established, some messages travel in the clear — but an intruder cannot do anything with them.

  1. Parameter request

    The client sends the server a randomly generated 128-bit nonce. This nonce identifies the client for the duration of the exchange. After this step, it is known to both parties.

  2. Server response

    The server returns: the client's nonce, its own 128-bit nonce, an integer pq (product of two odd primes) and a fingerprint of its RSA public key. The (client nonce, server nonce) pair identifies the couple for the whole exchange — an intruder cannot spin up a parallel session with the same parameters, since a fresh server nonce is generated for every attempt.

  3. Factorization of pq

    The client decomposes pq into its prime factors p and q. At this point, the Diffie-Hellman exchange can begin.

  4. RSA-encrypted envelope

    The client generates a new random 256-bit nonce, builds a message m containing pq, p, q, the nonce pair and this new nonce, then encrypts it with the server's RSA public key as shown below. After this step, the new nonce is known only to the client and the server.

    $$m = pq \mathbin\Vert p \mathbin\Vert q \mathbin\Vert \text{(nonce pair)} \mathbin\Vert \text{(new nonce)}$$
    $$m_{1} = \mathrm{sha1}(m) \mathbin\Vert m \mathbin\Vert \text{rand}$$
    $$\mathrm{RSA}_{\mathrm{pub}}(m_{1})$$

    rand pads $m_{1}$ to 255 bytes.

    Man-in-the-middle protection

    An intruder can intercept this request and replace it with their own, but they would have to regenerate their own new nonce without ever being able to decrypt m₁. Since every subsequent message contains the hash of that new nonce, the values will diverge on the client side and be rejected at verification. The interception simply causes the session to fail on the client — nothing exploitable.

  5. AES-256 response

    The server replies with the nonce pair and an AES-256 encrypted message containing the last 128 bits of the SHA-1 of the new nonce, the nonce pair, an integer g, a 2048-bit prime p, and g_a. The client knows for certain the reply comes from the server, since it is encrypted with a key derived from the new nonce.

    $$g\_a = g^{a} \bmod p$$

    where $a$ is a 2048-bit integer known only to the server.

  6. Client contribution

    The client picks b, a random 2048-bit integer, and sends the server the nonce pair along with an AES-256-CBC message containing g_b.

    $$g\_b = g^{b} \bmod p$$
  7. Session key derivation

    The session key is computed independently on both sides. The two results are mathematically identical.

    $$\text{server:}\quad (g\_b)^{a} \bmod p$$
    $$\text{client:}\quad (g\_a)^{b} \bmod p$$
    = $$g^{ab} \bmod p$$

    This 2048-bit key is never transmitted over the network.

  8. Session key identifier

    The last 64 bits of the SHA-1 of the session key serve as a public identifier, letting the server locate the correct key for each incoming message.

    $$\text{authKeyId} = \mathrm{substr}(\mathrm{sha1}(\text{(session key)}),\, -64,\, 64)$$

End of the process. All messages may now be exchanged securely, following the structure described below.

05 — Message structure

What an observer on the wire sees

Every message exchanged after session establishment is made of three blocks. Here is what an observer on the wire sees — and what they cannot.

Session key identifier
64 bits
Message key
128 bits
Encrypted payload
multiple of 128 bits
Session key identifier Lets the server locate the session key in memory. The key itself never travels.
Message key The last 128 bits of the SHA-1 of the plaintext message. Used to derive the AES key set and guarantees integrity: any alteration produces a different message key, and decryption fails.
Encrypted payload Encrypted in AES-256-CBC. Contains the message identifier, the size of the data, and the data itself. Random padding fills the payload to a multiple of 128 bits.
06 — AES key set derivation

How the AES key is derived per message

The session key (2048 bits) and the message key (128 bits) are used to compute the AES key set applied to a message. The AES key and initialization vector never travel over the network; each endpoint recomputes them from the same algorithm.

Notation

Derivation

$$\lambda = \mathrm{sha1}(MK \mathbin\Vert \mathrm{substr}(SK,\; \mathit{Offset},\; 32))$$
$$\alpha = \mathrm{sha1}(\mathrm{substr}(SK,\; 32 + \mathit{Offset},\; 16) \mathbin\Vert MK \mathbin\Vert \mathrm{substr}(SK,\; 48 + \mathit{Offset},\; 16))$$
$$\beta = \mathrm{sha1}(\mathrm{substr}(SK,\; 64 + \mathit{Offset},\; 32) \mathbin\Vert MK)$$
$$\Omega = \mathrm{sha1}(MK \mathbin\Vert \mathrm{substr}(SK,\; 96 + \mathit{Offset},\; 32))$$
$$x = \mathrm{substr}(\lambda, 0, 8) \mathbin\Vert \mathrm{substr}(\alpha, 8, 12) \mathbin\Vert \mathrm{substr}(\beta, 4, 12)$$
$$y = \mathrm{substr}(\lambda, 8, 6) \mathbin\Vert \mathrm{substr}(\alpha, 0, 8) \mathbin\Vert \mathrm{substr}(\beta, 16, 2) \mathbin\Vert \mathrm{substr}(\Omega, 0, 4)$$
$$\boxed{\text{AES key set} = x \mathbin\Vert y}$$

The 48-byte result splits into 32 bytes of AES key and 16 bytes of initialization vector. When the data length is not a multiple of 16 bytes, random padding is appended before encryption.

07 — Guarantees

What japap promises

Beyond the primitives and their composition, japap guarantees you three fundamental properties, mathematically verifiable.

Confidentiality

Only the holder of the session key can decrypt the content. Without that key, AES-256 in CBC mode is considered beyond the reach of any reasonably accessible computing power.

Integrity

Any modification of the ciphertext — even a single byte — produces a corrupted message whose message key no longer matches. The frame is rejected before it reaches business logic.

Authenticity

The message key can only be produced by a device holding the session key. The server therefore knows each message comes from an authenticated client, with no possible ambiguity.

08 — Contact us

Let us talk

Our security team answers every question. Researcher, integrator, curious user: write to us, we reply.

operations@ondjoss.com

BACK