diff --git a/protocol.md b/protocol.md index 96123a7..8fc2a02 100644 --- a/protocol.md +++ b/protocol.md @@ -1,108 +1,59 @@ # The Protocol -All encryptions are made using RSA (key size to be determined), no symmetric encryptions -are used due to messages being short. -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 +doesnt seem to be any reason to use a key derivation function. ## 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 `VerificationRequired` message & a 6-digit code (Secure channel) -- 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 +- User sends a `Register` requset giving them a public key and encrypting using the server's public key +- Server sends the user a `VerificationRequired` (not in current code, as the 6 digit code does that for now) message & a 6-digit code (Secure channel) +- User sends the server a `ConfirmRegister` with the 6-digit code, signed using the key provided at previous stage +- Server verifies the signature and code, and if both are valid it sends a last `Confirm` and the registration process is done -## "Login" +## 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 +Login is done by a challenge, the user sends a `Login` request, the server sends a random block of 16 bytes for the user to sign, +then the server validates the signature with the known saved key. ## 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. +A will then encrypt the message using B's key, append a signature, and send a `SendMessage` +request with the payload having the structure of `Enc_b(Message object) + Signature_A(Message object)`. The server will hold on to the message until B will send a `GetMessages` request to the server. -## "Control" requests +## Requests - Register: data: Phone - 8 bytes, RSA key size (payload length) - 2 bytes - ConfirmRegister (signed & encrypted 6 digit code) - data: 6 bytes for the 6 digit code (can use less but it will be padding otherwise) + data: 6 bytes for the 6 digit code, 4 bytes for signature length - Login: data: 8 bytes of user's phone - ConfirmLogin (signed hash): data: hash length - GetMessages: 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) +- GetUserKey: 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)` +- SendMessage: extra data: 8 bytes (4 bits per digit) of who to send the data, 4 bytes (32bit) for length in bytes I think it all can go into a: ``` { - Version byte (0) - 1 byte + Version byte (0) - 1 byte, RequestType - 1 byte, - looping counter - 1 bytes (long), could be replaced by a counter, that can be 1 looping byte, thus + looping counter - 1 byte, data - up to 13, } = 16 bytes = 128 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, this shit really feels like overkill and im not sure about it, -on the other i do want to have a bigger key size and 512 seems like an okay-ish thing to have, as 256 is short and 1024 is -amusingly long for the amount of data the server needs to encrypt - -enc_server( request - 256 bits, signed sha3-256 ) - -which means: - public keys: RSA-2048/1024 (not sure what i need here honestly) +Encryption and Hashes used: + public keys: RSA-1024 (can be of somewhat arbitrary length) Hashes: SHA3-256 - symmetric keys: AES-256 - -scrape that... seems it wouldnt work as expected since it doesnt work that way -with RSA i think maybe not im not sure... - -thinking right now about an RSA-2048 key (for sEcUrItY), -then starting a connection will be whatever the user wants, and optionally -an AES-128 (because its only for 1 session) key to use for subsequent messages, -this allows the user to NOT encrypt everything with RSA keys, it still means the -server has to decrypt and verify a signature for the first message (and either return -an error or force close the connection if the sig is invalid and all) - -this somewhat applies for the register messages, you send a payload with an AES key -and a public RSA key, then in `ConfirmRegister` the key is still being signed with -the user's RSA, but then encrypted using the AES session key. - -Messages between users will still be done using public RSA keys, -which honestly can be both 1024, or 2048 as far as im aware, prob should also be -2048, that means the server needs to do 2 RSA encryptions per session -(or 2 for the registration itself, which is then auto-validating the session) - + symmetric keys: AES-CFB-256 with PCKS7 padding (when needed as most stuff are made to fit in 1 block)