OneTime offers a secure way of sharing secrets. While conceiving this system, we wanted to trust as few parties as possible. This includes our servers: When you provide your secrets, OneTime encrypts them in your browsers. At no time will your secrets be visible to our servers.
This visual representation gives a good overview:
When you provide your secret to the OneTime website, a random ciphering key is selected which is used to encrypt your secret. The encryption happens in your browser, so our server never sees the password in cleartext. After the encrypted material is filed to the server, the server returns a retrieval URL. Your browser finally appends the encryption key to the URL and shows it to the user.
The retrieval of a secret is very similar, in the inverted order.
This section provides more information for people that have a solid base knowledge in cryptography, web technologies, and computer science in general.
Let's start with a reminder of Kerckhoffs' principle:
Il faut qu[e le système] n’exige pas le secret, et qu’il puisse sans inconvénient tomber entre les mains de l’ennemi;
[The system must not require secrecy and can be stolen by the enemy without causing trouble;]
A modern interpretation of this principle is that a secure system is only secure if and only if it stays secure when everything, but the cryptographic keys, are published. This means that showing in detail how our password sharing system works, will not compromise its security in any way. Besides; as all cryptographic operations are executed in your browser, you should be able to verify every information you'll find on this page by inspecting the JavaScript source code.
To protect the secrets before sending them to the server, they are locally encrypted. To that end, the Crypto WebAPI, a cryptography library directly integrated in the user's browser, is used. As cipher, we chose AES-GCM (AES in Galois/Counter Mode). More specifically, AES-GCM is used with a key size of 256 bytes. GCM offers many advantages, like the integrated integrity protection: it includes message authentication codes (MACs), such that tampered ciphertexts can immediately be discarded.
As it would be impractical to include a 256 bytes encryption key in a retrieval URL, a 16 bytes key is randomly generated and, together with another randomly generated 16 bytes salt, injected to a key derivation function (PBKDF2). As hash function, PBKDF2 uses SHA-256. To counter brute force attacks, 310'000 iterations are used. The output of this key derivation function is a 256 bytes long ciphering key. The last cryptographic element (of the encryption) is the initialisation vector (IV) given to the AES-GCM procedure. For this, the client chooses a random 12 bytes array. The total amount of entropy of the whole encryption is, due to the initial key length, 16 bytes. This means that there exist 2128 ≈ 3.4028 • 1038 possible keys that an attacker has to try. The security of the key is thus roughly equivalent to a randomly generated 20-ascii-characters password.
After generating every cryptographic element and performing the encryption, everything but the encryption key is sent to the server. The encryption key is encoded in base64 and appended as URI fragment (string part behind the # in the URI) of the retrieval URL. The advantage of that fragment is that it is never sent to the server, so the server will never get to know the ciphering key.
For decryption, the server provides the different byte arrays (salt, IV, ...) to the browser, which uses them, together with the key included in the URL fragment, to decrypt the secret. (This is a simplification which will be further elaborated in the following sections.)
For added security, the user has the possibility to provide an out-of-band password. This password is required to decrypt the password and, contrary to the initial 16 bytes key, is not appended to the retrieval URL. The idea of the out-of-band password is to have an additional password that should be transmitted on another channel than the primary decryption key (the one contained in the retrieval URL). That other channel could e.g. be a telephone connection, a chat message in Microsoft Teams, or even an offline pre-shared-secret.
During encryption, this password is appended to the initial key, before being provided to the key derivation function. This means that any password drastically alters the ciphering key, without removing any security. The user is responsible to choose a secure password, but even in the worst case, the encryption entropy is the same as using no out-of-band password. In an average case, it provides a few bits of additional entropy.
In practice, the reason to use an out-of-band password is not the added entropy, but the separation of the decryption key on two channels: If the mailbox of the receiving user is compromised, they need to additionally get hold of the separately handled password.
One disadvantage of using AES in GCM is the exposed length of the plaintext. As the length of a password is already a valuable information for attackers, BCE OneTime pads all secrets to a block size of 255 bytes using PKCS7 padding before encrypting them. If the secrets are files, they are also padded, even though the size is not as valuable in such a case.
To make offline brute force impossible, it must be assured that the encrypted secret is only transmitted to the client (browser) if the client can prove that it knows the encryption key.
To that end, the browser takes the initial key and (cryptographically) hashes it with SHA-256, together with a randomly chosen 16 bytes salt. The resulting hash is provided to the server upon upload of the encrypted secret. As it is preimage-resistant, the server is not able to convert it back to the initial key.
If a user tries to retrieve the secret, they need to provide the same hash, proving that they know the key. The salt is provided to them by the server.
Using this verification process also allows for server-side enforced secret deletion upon retrieval. This guarantees that secrets are only retrieved once, allowing the retrieving user to be assured that nobody else saw the secret.
Finally, the server-validation allows for an online brute force protection. Each time a false key (initial key or out-of-band password) is provided, the action is recorded. An exponential time offset is then enforced between trials. After 10 tries, the secret is deleted from the server.