2024-12-01 17:40:08 +00:00
|
|
|
# The Protocol
|
|
|
|
|
|
|
|
All encryptions are made using RSA (key size to be determined), no symmetric encryptions
|
|
|
|
are used due to messages being short.
|
|
|
|
|
2024-12-14 15:17:58 +00:00
|
|
|
a. Encryption will be a-symmetric because we can assume messages are short
|
|
|
|
b. See "Registration" below
|
|
|
|
c. Server keeps public keys for everyone, and gives them to a user when they want to
|
|
|
|
send a message to someone (only the relevant key)
|
|
|
|
d. Every e2e message is both signed and encrypted aka, message M from A to B
|
|
|
|
`EM = E_Bpub(E_Apriv(N))`
|
|
|
|
e. message is sent to the server in a `E_server(E_Apriv(metadata + EM from d))`,
|
|
|
|
message ack is sent to the server as a `MessageAck(msg_id)`, which will be retrieved
|
|
|
|
by the user when it pulls for messages.
|
|
|
|
f. TODO: properly explain the different api structs
|
|
|
|
g. TODO: properly explain how the server handles data
|
|
|
|
|
|
|
|
### Key Derivation Function
|
|
|
|
|
|
|
|
as there is no use of symmetric keys (at least for this scope), I dont believe there
|
|
|
|
is a need to use KDF, it will reduce the keyspace and we already have the public key
|
|
|
|
of the server in the clients
|
|
|
|
|
2024-12-01 17:40:08 +00:00
|
|
|
## Registration:
|
|
|
|
|
|
|
|
- User sends a register request to server `(phone number, RSA public key)`,
|
|
|
|
giving them a public key and encrypting using the server's public key
|
2024-12-14 15:17:58 +00:00
|
|
|
- Server sends the user a `VerificationRequired` message & a 6-digit code (Secure channel)
|
2024-12-01 17:40:08 +00:00
|
|
|
- User sends the server the 6-digit code, signed using the key provided at stage 1
|
|
|
|
(this message is very short and funny, because its a 6-digit code, signed using the
|
|
|
|
user's private key, and encrypted using the server's public key)
|
|
|
|
- Server sends a last `Confirm` and the registration process is done
|
|
|
|
|
|
|
|
## "Login"
|
|
|
|
|
|
|
|
The users dont need to login, as they dont really need to hold a conenction
|
|
|
|
to the server, only thing that matters is that every message to the server should
|
|
|
|
be signed with the user's private key, thus the key acts as a form of credentials
|
|
|
|
|
|
|
|
## Passing messages
|
|
|
|
|
|
|
|
In order to send a message from A to B, A will ask the server for B's key,
|
|
|
|
A will then encrypt the message using B's key, signed with A, wrapped in a `SendMessage`
|
|
|
|
request and ultimately signed by A and encrypted using the server's key.
|
|
|
|
|
|
|
|
The server will hold on to the message until B will send a `GetMessages` request
|
|
|
|
to the server.
|
2024-12-14 15:17:58 +00:00
|
|
|
|
|
|
|
## "Control" requests
|
|
|
|
|
|
|
|
- Register `(phone, pub RSA key)`
|
|
|
|
extra data: RSA key size (payload length)
|
|
|
|
- ConfirmRegister (signed & encrypted 6 digit code)
|
|
|
|
extra data: 6 bytes for the 6 digit code (can use less but it will be padding otherwise)
|
|
|
|
- GetMessages (signed & encrypted to not allow someone to "flush" someone else's msgs)
|
|
|
|
extra data: EMPTY
|
|
|
|
- GetUserKey (dont think it needs any signing or encryption technically, as it is very
|
|
|
|
simple registering and "stealing" a key outside the system, keys are assumed to be
|
|
|
|
unbreakable)
|
|
|
|
extra data: 8 bytes (4 bits per digit) of whoever we want to get the key of
|
|
|
|
- SendMessage `(to_user, msg_id, EM from d above)`
|
|
|
|
extra data: 8 bytes (4 bits per digit) of who to send the data, 4 bytes (32bit) for length
|
|
|
|
- SendAck `(to_user, msg_id - signed and encrypted)`
|
|
|
|
- server doesnt know if the msg itself is indeed valid and not tempered with
|
|
|
|
extra data: 8 bytes (4 bits per digit) of who to send the data, 4 bytes (32bit) for length
|
|
|
|
|
|
|
|
I think it all can go into a:
|
|
|
|
```
|
|
|
|
{
|
|
|
|
Version byte (0) - 1 byte
|
|
|
|
RequestType - 1 byte,
|
|
|
|
Phone number - 8 bytes (every 4 bits is a number, so we have 16 numbers),
|
|
|
|
UTC timestamp - 8 bytes (long),
|
|
|
|
extra data (based on the request given) - up to 18 bytes
|
|
|
|
} = 32 bytes = 256 bits
|
|
|
|
```
|
|
|
|
and we can just append encrypted payloads to it (in SendMessage and SendAck)
|
|
|
|
|
|
|
|
To each message we also append a sha3-256 signed hash
|
|
|
|
|
|
|
|
enc_server( request - 256 bits, signed sha3-256 )
|
|
|
|
|
|
|
|
which means:
|
|
|
|
Keys: RSA-512
|
|
|
|
Hashes: SHA3-256
|