docs: update connection diagram to include user-server authentication and encryption

This commit is contained in:
Evgeny Poberezkin
2019-12-21 22:20:02 +00:00
parent 85998d9e8e
commit 902c2007dc
3 changed files with 221 additions and 164 deletions
+52 -18
View File
@@ -1,24 +1,58 @@
sequenceDiagram
participant Alice
participant App A
participant Server A
participant Server B
participant App B
participant App A as Alice's app
participant Server A as Alice's server
participant Server B as Bob's server
participant App B as Bob's app
participant Bob
Alice ->> App A: Alice shows <AB public key> as QR code on the screen<br>(Alice's public key for Bob's eyes only)
Bob ->> App B: Bob requests app to add connection
App A ->> App B: Bob's app reads <AB public key> via the camera
App B ->> Server B: Bob's app encrypts "connection request" (including <BA public key> and Bob's profile) and sends it to Bob's servers<br>{from: <BA public key hash>, to: <AB public key hash>, message: <request encrypted with AB public key>}
Server B ->> Server A: Bob's servers use <AB public key hash> to locate Alice's servers<br>and forward encrypted message to all Alice's servers (when they are different from Bob's servers)
Server A ->> App A: Alice's servers send the message to Alice's app
App A ->> Alice: Alice's app matches <AB public key hash> with shown QR code<br>and decrypts Bob's profile with <AB private key> to show it
Alice ->> App A: Alice requests app to initiate adding connection
Note over App A: App generates:<br><AB connection key><br><A_AB server keys>
App A ->> Server A: App registers on Alice's servers <AB public key hash> associated with <A_AB server public keys> (for recepient)
App A ->> Server A: App subsribes to receive messages from anyone sent to <AB public key hash><br>(request is signed with <A_AB server private keys>)
Note over App A: App shows QR code<br>for <AB public key><br>and Alice's servers
App A -->> Bob: Alice shows to Bob <AB public key> and her servers as QR code on the screen<br>(Alice's public key for Bob only and servers she currently uses)
Bob ->> App B: Bob requests app to read connection QR code
App A -->> App B: Bob's app reads QR code with <AB public key> and Alice's current servers via the camera
Note over App B: App generates<br><BA connection key><br><B_BA server keys>
App B ->> Server B: App registers on Bob's server <BA public key hash> associated with <B_BA server public keys> (for recepient)
App B ->> Server B: App subsribes to receive messages from anyone sent to <BA public key hash><br>(request is signed with <B_BA server private key>)
Note over App A, App B: Now both Alice's and Bob's apps are subscribed to receive each other's messages on their servers
Note over App B: App generates<br><B_AB server keys><br>for Alice's servers<br>and creates<br>connection request<br>including:<br>- <BA public key><br>- Bob's profile<br>- Bob's servers<br>- <B_AB public keys>
App B ->> Server A: Bob's app encrypts "connection request" with <AB public key> and sends it to Alice's servers<br>{to: <AB public key hash>, message: <request encrypted with AB public key>}
Server A ->> App A: Alice's servers send "connection request" to Alice's app<br>(as <AB public key hash> allows messages from anyone)
App A ->> Alice: Alice's app matches <AB public key hash> with <AB public key><br>and decrypts Bob's profile with <AB private key> to show it
Alice ->> App A: Alice identifies Bob's profile and accepts the connection<br>(Bob is now added to Alice's list of connections as "pending")
App A ->> Server A: Alice's app creates "connection accepted" message (including Alice's profile) and sends it to Alice's servers<br>{from: <AB public key hash>, to: <BA public key hash>, message: <encrypted with AB public key>}
Server A ->> Server B: Alice's servers use <BA public key hash> to locate Bob's servers<br>and forward encrypted message to all Bob's servers (when they are different from Alice's servers)
App A ->> Server A: App registers on Alice's servers <AB public key hash> associated with <B_AB server public keys> (for sender)
Note over Server A, Bob: Now only Bob's app can send messages for <AB public key hash> to Alice's servers<br>1) signed using <BA private key><br>2) encrypted using <AB public key><br>3) signed/encrypted using <B_AB server private/public keys>
Note over App A: App generates<br><A_BA server keys><br>for Bob's servers<br>and creates<br>"conn. accepted"<br>message including:<br>- Alice's profile<br>- <A_BA public keys>
App A ->> Server B: Alice's app signs "connection accepted" with <AB private key>, encrypts it with <BA public key> and sends it to Bob's servers<br>{to: <BA public key hash>, message: <encrypted with BA public key>}
Server B ->> App B: Bob's servers send the message to Bob's app
App B ->> Bob: Bob's app matches <AB public key hash> with read QR code<br>and decrypts the Alice's profile with Bob's <BA private key>
App B ->> Bob: Bob's app adds Alice to the list of connections
App B ->> Server B: "connection acknowledgement" message
Server B ->> Server A: "connection acknowledgement" message
Server A ->> App A: "connection acknowledgement" message
App B ->> Bob: Bob's app matches <BA public key hash> with <BA public key><br>and decrypts the Alice's profile with Bob's <BA private key>
App B ->> Bob: Bob's app shows Alice's profile and adds it to the connections<br>(as pending)
App B ->> Server B: App registers on Bob's servers <BA public key hash> associated with <A_BA server public keys> (for sender)
Note over Alice, Server B: Now only Alice's app can send messages for <BA public key hash> to Bob's servers<br>1) signed using <AB private key><br>2) encrypted using <BA public key><br>3) signed/encrypted using <A_BA server private/public keys>
Note over App B: App creates<br>"connection<br>acknowledged"
App B ->> Server A: Bob's app signs "connection acknowledged" with <BA private key>, encrypts it with <AB public key> and sends it to Alices's servers<br>{to: <AB public key hash>, message: <encrypted with AB public key>} (also signed/encrypted with B_AB server private/public keys)
Server A ->> App A: Alice's servers send to app "connection acknowledged"
App A ->> Alice: Bob is now in the Alice's list of connections as "established"
Note over App A: App creates<br>"connection<br>acknowledged"
App A ->> Server B: Alice's app signs "connection acknowledged" with <AB private key>, encrypts it with <BA public key> and sends it to Bob's servers<br>{to: <BA public key hash>, message: <encrypted with BA public key>} (also signed/encrypted with A_BA server private/public keys)
Server B ->> App B: Bob's servers send to app "connection acknowledged"
App B ->> Bob: Alice is now in the Bob's list of connections as "established"
Note over Alice, Bob: Now Alice and Bob can exchange messages with each other, including key rotations and changes of servers they use<br>- Alice can send messages to Bob's servers to <BA public key hash> (Bob's servers allow Alice to send messages relying on A_BA keys)<br>- Bob can subscribe to messages on his servers sent to <BA public key hash> (Bob's servers allow Bob to receive messages relying on B_BA keys)<br><br>- Bob can send messages to Alice's servers to <AB public key hash> (Alice's servers allow Bob to send messages relying on B_AB keys)<br>- Alice can subscribe to messages on her servers sent to <AB public key hash> (ALice's servers allow Alice to receive messages relying on A_AB keys)
+143 -143
View File
File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 32 KiB

+26 -3
View File
@@ -27,7 +27,7 @@ The problems of existing chat solutions this system intends to solve:
- Public keys used between connections are regularly updated to prevent decryption of the full message history in case when some servers or middle-men preserve message history and the current key is compromised.
- Users can repeat key exchange using QR code and alternative channel at any point to increase communication security.
- No single server in the system has visibility of all connections or messages of any user, as user profiles are identified by multiple rotating public keys, using separate key for each profile connection.
- Servers only store hashes of public keys, so that nobody can encrypt messages from a user profile connection, other than the user who has this public key (effectively making it a signature of the connected user). (Question: maybe connection key pair used to encrypt should be different from the key pair used to sign?)
- Servers only store hashes of public keys, so that nobody can encrypt messages from a user profile connection, other than the user who has this public key (effectively making it a signature of the connected user).
- User profile (meta-data of the user including non-unique name / handle and optional additional data, e.g. avatar and status) is stored in the client apps and is shared only with accepted user profile connections.
@@ -73,14 +73,37 @@ Client apps should provide the following:
- store history of all conversations encrypted using user client app password (or some other device specific encryption mechanism).
## Sequence diagrams
## System design
Prepared with [mermaid-js](https://mermaid-js.github.io/mermaid-live-editor)
### Adding connection
### Connections between user profiles
The system uses connections between user profiles (no information identifying user is stored on the servers) to send and to receive messages. Each connection is one-directional, from sender to recepient, without any correlation between connections and user profiles, and between 2 connections used to send and to receive messages between the same participants.
This design aims to reduce the risk of correlating communication of a user profile with other user profiles (to keep the list of connections private), and of correlating sent and received messages between the same participants.
Sockets used to send and receive connections can be used by an attacker for such correlation; to avoid it user profiles can be configured to use separate sockets for each one-directional connection (and in case of limited number of sockets, they can be closed and new sockets can be opened to avoid the possibility of any correlation, other than on network level). The probability of network level correlation can be further reduced with onion routing of messages.
Each one-directional connection is identified by two key pairs for each participant. Each connection participant registers on the server \<connection public key hash\> and \<server public key\> for each connection.
All keys are generated by the user. Server keys are used for communication between server and user (for server to encrypt AND for user to sign). Connection keys are used for E2EE between users (for sender to encrypt using recepient's connection-specific public key and to sign using sender's connection-specific private key). For all keys, client app sends to all user's servers \<server public key\> and \<connection public key hash\>.
Each connection can be used as inbound or as outbound - from the database point of view they look the same (to make any analysis more difficult for the attacker). Only the client app determines how each connection is used - as inbound or as outbound.
For each inbound connection two keys allow to subscribe to receive messages from connection (by sending \<connection public key hash\> signed by \<server private key\> - server will be able to match it with connections database and accept such request to deliver messages from connection via the subscribed socket) and to decrypt server-side encryption of messages sent from (and separately encrypted by) connection using the \<server private key\>.
Each key tuple for outbound connetion will allow user to send messages to connection (by signing messages, including \<connection public key hash\>, with \<server private key\> - server will be able to match it with connections database and accept such messages) and to decrypt any service messages and responses using the \<server private key\>.
In this way the server will only have the list of connections via which messages can be sent or received (identified by \<connection public key hash\>), associated public keys to authenticate senders and recievers (\<server public key\>), with a separate server public key for each connection participant. The attacker will not be able to establish that any list of connections belongs to the same user (other than by analysing socket or network traffic).
### Establishing connection between user profiles
![Adding connection](/diagrams/connection.svg)
### Sending message
![Sending message](/diagrams/message.svg)