This document explains the cryptographic protocol used to implement end-to-end encryption for share links.
- User enters
plaintext
, chooses expiration details (max_views
andmax_days
), and clicks submit to create a new share link. - Client uses a CSPRNG to generate a new, random 64-byte
passphrase
. - Client uses a CSPRNG to generate a new, random 64-byte
passphrase_salt
. - Client uses a CSPRNG to generate a new, random 12-byte
aes_iv
(initialization vector). - Client computes
HMAC_SIGN(plaintext, passphrase)
to derive theid
of this share link. In addition to serving as the primary key, this will later be used as a final authenticity check when decrypting. - Client computes
SHA256(passphrase)
to derive thepassphrase_digest
. This will later be used to authenticate a request to view the share link's content. - Client computes
HKDF(passphrase, passphrase_salt)
to derive the 32-byte symmetric encryptionkey
. - Client computes
AES_GCM_ENCRYPT(plaintext, aes_iv, key)
to derive theciphertext
. - Client sends a request to Server. The request contains the
id
,passphrase_salt
,passphrase_digest
,aes_iv
,ciphertext
,max_views
, andmax_days
. NOTE:key
,passphrase
, andplaintext
are NEVER sent to Server. - Server validates the share link parameters included in the request and creates a new record for this share link in the database if valid.
- On success, Client reveals the share link URL, i.e.,
https://<host>/s/<id>#<passphrase>
, to the user. NOTE: Thepassphrase
is in the URL hash so that browsers do not send it to Server. - User can copy the link and share it with whomever.
- User visits the view page using the previously generated share link, i.e.,
https://<host>/s/<id>#<passphrase>
. - Server verifies the share link with this
id
exists.- IF it exists and is not considered expired, THEN Server responds with the view page content.
- ELSE, user is redirected to home page.
- User clicks 'View Secret' button.
- Client takes the
passphrase
from the URL hash and computesSHA256(passphrase)
to derive thepassphrase_digest
. - Client sends a request to Server to view this share link. The request includes the
passphrase_digest
.- IF the share link is not considered expired AND the
passphrase_digest
matches the entry in the database (thereby authenticating the request), THEN Server increments the share link'sviews
and its response includes thepassphrase_salt
,aes_iv
, andciphertext
. - ELSE user is notified of an error.
- IF the share link is not considered expired AND the
- Client computes
HKDF(passphrase, passphrase_salt)
to derive the 32-byte symmetric encryptionkey
. - Client computes
AES_GCM_DECRYPT(ciphertext, aes_iv, key)
to derive theplaintext
. - Using the decrypted
plaintext
, Client verifies that theid
from the URL is in fact the result ofHMAC_SIGN(plaintext, passphrase)
by computingHMAC_VERIFY(id, plaintext, passphrase)
.- IF HMAC verification fails, something is terribly wrong, and an error will be shown to the user. NOTE: This should never happen.
- While somewhat redundant with authenticated encryption, this helps ensure the authenticity and integrity of the overall process.
- The
plaintext
is revealed to the user.
- The
id
is Base58-encoded. - The
passphrase
in the URL hash is Base58-encoded. - The
passphrase_digest
is Base16-encoded. - The
passphrase_salt
,aes_iv
, andciphertext
are all Base64-encoded. - Computing the
id
from thepassphrase
andplaintext
is not strictly necessary. Theid
consists of two secret values:passphrase
andplaintext
. This means we're accessing the data by an identifier that corresponds to the underlying content, essentially making the data in the system content-addressible. This is a desirable property for this system. While this may be redundant due to use of authenticated encryption, it's nice that it also serves as a final authenticity check that the protocol was executed properly.