Skip to content

Commit 71020fd

Browse files

File tree

1 file changed

+44
-0
lines changed

1 file changed

+44
-0
lines changed

zaps/0002-encrypt-push-notifications.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,47 @@ and so will not cause older servers to send it notifications.
9595
Eventually, we will remove support for the old protocol, at which
9696
point these settings will be removed.
9797

98+
99+
## Cryptographic choices
100+
101+
Notifications are sent with authenticated encryption, meaning
102+
the cryptography provides confidentiality (the data cannot be read
103+
by parties lacking the appropriate secret key) and also
104+
authenticity (the message cannot be forged or altered by a party
105+
lacking the appropriate secret key).
106+
107+
Notifications are encrypted with symmetric cryptography, using a
108+
secret key shared by an individual client (the Zulip app on a
109+
given user device) and a Zulip server.
110+
Specifically, the server encrypts them using libsodium's
111+
`crypto_secretbox_easy` ([doc][libsodium-secretbox];
112+
[NaCl doc][nacl-secretbox]), which uses XSalsa20 and Poly1305
113+
to provide authenticated encryption.
114+
This calls for a 192-bit nonce, which the server chooses randomly
115+
on each occasion.
116+
117+
In the Python-like pseudocode types below, `SymmetricKey` refers
118+
to a key used for this cryptosystem, 32 bytes in length.
119+
120+
When registering to receive notifications (as detailed
121+
[below](#register)), the client encrypts certain data
122+
to be read only by the bouncer.
123+
This encryption is done with asymmetric cryptography, using
124+
a public key which belongs to the bouncer
125+
(called `bouncer_public_key` below) and is baked into the client app.
126+
Specifically, the client encrypts this data using libsodium's
127+
`crypto_box_seal` ([doc][libsodium-box]; [NaCl doc][nacl-box]),
128+
which uses Curve25519, XSalsa20, and Poly1305.
129+
130+
In the Python-like pseudocode types below, `PublicKey` refers to a
131+
public key used for this cryptosystem, 32 bytes in length.
132+
133+
[libsodium-secretbox]: https://libsodium.gitbook.io/doc/secret-key_cryptography/secretbox
134+
[nacl-secretbox]: https://nacl.cr.yp.to/secretbox.html
135+
[libsodium-box]: https://libsodium.gitbook.io/doc/public-key_cryptography/sealed_boxes
136+
[nacl-box]: https://nacl.cr.yp.to/box.html
137+
138+
98139
## Data structures
99140

100141
Once a given client has logged into a server and the setup phase of
@@ -304,6 +345,9 @@ The steps are:
304345

305346
1. Process the resulting plaintext as a notification.
306347

348+
349+
<div id="register" />
350+
307351
### Registering a client device
308352

309353
This operation occurs after a client logs into a Zulip server and

0 commit comments

Comments
 (0)