69 lines
3 KiB
Markdown
69 lines
3 KiB
Markdown
# The Protocol
|
|
|
|
All encryptions are made using RSA (key size to be determined), no symmetric encryptions
|
|
are used due to messages being short.
|
|
|
|
<!-- Maybe yse RSA-256 (or the closest)? if i can assume it is unbreakable that is -->
|
|
## Some problems
|
|
|
|
Do i need hasing? dont think it will help too much, can just sign-encrypt i think.
|
|
|
|
When asking for messages, maybe do a little back and forth with the server to make sure
|
|
the request comes from the correct person?
|
|
Maybe keep track of the last message ID every time? then add it to the request,
|
|
not good, as if there were no new messages an attacker can now use said req.
|
|
Maybe the current timestamp? then the server keeps track of the last request with
|
|
timestamp for a given user? kinda acts like a better counter i think.
|
|
I dont think someone can abuse this system.
|
|
I think adding this to every request is neccessary to make sure no duplicates are
|
|
being sent, ie. if an attacker listens on the channel and sees a package sent to
|
|
the server, it can repeat it and cause mischief (maybe send duplicate messages,
|
|
or flush the user's messages or something).
|
|
|
|
an attacker can also abuse duplicates to see who a user is talking to,
|
|
simply send the request and encrypt all public keys (gotten in a legitimate way)
|
|
using the user's public key (as the server would encrypt) and compare the result
|
|
from the server
|
|
|
|
|
|
## 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
|
|
- Server sends the user a `Confirm` message & a 6-digit code
|
|
- 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.
|
|
|
|
## Requests:
|
|
|
|
legend:
|
|
- `E(t)` encrypt t
|
|
- `S(t)` sign t
|
|
- `ES(t)` signed and encrypted (in that order!)
|
|
- `HS(t)`/`HS t` hash and sign t
|
|
All requests are to be encrypted using the server's public key, have the sender phone
|
|
and have a timestamp on them, except when otherwise noted
|
|
|
|
1. `Register(public key)`, no timestamp
|
|
2. `HS RegisterConfirm(6-digit code)`
|
|
3. `GetMessages`
|
|
4. `GetUserKey(phone - user to get key for)`
|
|
5. `SendMessage(phone - receiver, ES({ message_id, message }))`
|
|
6. `SendMessageACK(phone - ack receiver, ES({ message_id[], ACK/NACK }))`
|