Why is transientsecret.com secure?
Secrets are encrypted and decrypted in the browser, i.e. the encryption is end-to-end. Also, a proof is sent to the backend that is able to decide if the requester knows the password. If the proof matches then the encrypted secret is sent for decryption in frontend. Anyhow, the data is deleted from the backend at any attempt (given the proof successful or not). Therefore, a sharing link only allows one attempt, disabling possible brute force attacks on leaked links.
Encrypt
The process of encrypting is as follows:
secret
andkey
are the inputs- A random byte array is generated named
saltId
and with thekey
used to generate thekeyId
with PBKDF2. ThiskeyId
will be stored in the backend, thesaltId
is stored in the sharing url. - A random byte array is generated named
searchKey
and stored as is in the backend and in the sharing url. - A random byte array is generated named
salt
and used with thekey
to generate thesecretKey
with PBKDF2. Thesalt
will be stored in the backend. secretKey
is used to encrypt thesecret
with AES resulting insecretEncrypted
that is stored in the backend. Also, this step generatesiv
that is also stored in the backend.- Then
keyId
,searchKey
,salt
,iv
andsecretEncrypted
are sent to the backend and stored as base64 strings. - Then a url is generated with
searchKey
andsaltId
This process until step 6 happens in the file src/crypto.ts
function storeSecret
.
Decrypt
The process of decryption is as follows:
- The user opens the url containing
searchKey
andsaltId
- The user is prompted to input the
key
- The
key
and thesaltId
are used to generate thekeyId
as in encryption step 2 - The
searchKey
andkeyId
are sent to the backend to request the download of the stored data - The backend searches for a row with the same
searchKey
, if found the row is deleted. Then thekeyId
of the row is checked against the givenkeyId
, the data is returned on match. Otherwise, a404
is returned. - If the result wasn't a
404
then thesalt
,iv
andsecretEncrypted
are used to revert the steps 4 and 5 of the encryption process, generating the originalsecret
.
This process happens in the file src/crypto.ts
function retrieveSecret
, and the backend
logic of step 5 is located in pages/api/secret.ts
.
Where is the data?
Data stored in the backend:
keyId
, derived from thesaltId
andkey
searchKey
, a random byte arraysecretEncrypted
, the secret encryptedsalt
, a random byte array used to generatesecretKey
to encrypt thesecret
iv
, a random byte array used to run AES
Data stored in the sharing url:
searchKey
, a random byte arraysaltId
, a random byte array used to generatekeyId
The data stored in the sharing url is stored in the URI fragment, also known as hash, therefore it is not sent to the server. (Thanks wormhole.app for the inspiration)
Data not stored anywhere:
key
the user's input keysecret
the user's secret