Privacy Limited Features Pricing Blog About Contact Us

Encryption And Security In Denote

1 June 2022     By Denote


We at Privacy Tools have a few simple guidelines when building security products:

We want to elaborate on these principles, and make clear why you should trust us to encrypt your data.

Use Tried and True Techniques

In the encryption world, it takes time to find out if a new algorithm is good. It needs to be attacked by security researchers over many years before we can be sure that the algorithm is solid, well understood, and resistant to attacks. In the encryption world, you should generally assign more trust to older, battle hardened algorithms over shiny new ones.

As an example - the Rijndael algorithm was chosen, after a tough competition, to be the encryption algorithm specified in the Advanced Encryption Standard (AES) in 2001. Since then, it has had 20 years of attacks by cryptographers around the world. Various minor weaknesses have been found in that time, but nothing has come close to causing problems. We are confident that this algorithm, when used properly, is safe. This safety takes time.

Similarly, the ChaCha20 cipher we use for most encryption in Denote was first developed in 2008 and was based on an algorithm from 2005 (Salsa) and it has been under attack since then. Again, thanks to years of analysis, we are confident of its security.

In Denote, we tie ChaCha20 with Poly1305 - a MAC (Message Authentication Code) which allows us to verify the authenticity of any data decrypted, and also makes it difficult to take that data and decrypt it somewhere else by adding a context or Additional Authenticated Data (AAD) to every encrypted object. This hash, and therefore context, is verified on every decrypt. Poly1305 was developed in 2005. We use the expanded 96bit nonce as specified in RFC7539.

Lastly, ChaCha20 is more resistant to quantum attacks than AES, although neither are particularly threatened by quantum computers.

Use Well Defined Industry Standards

There are many examples of people trying to create their own encryption algorithms or implement existing algorithms themselves. All of these are destined for failure.

Rolling your own encryption is referred to as snake oil. Good encryption algorithms require time and significant expertise to build and test because they are hard to create. They also need long periods of study for weaknesses.

Every instance of designing your own encryption in an application has ended in disaster. It is improbable that your algorithm will be safe from:

Read "Memo to the Amateur Cipher Designer" here to learn more.

Use Well Maintained, Professionally Developed, And Simple Libraries

Professional software development is part art, part science. A well developed library has some identifying attributes:

Not all libraries exhibit these attributes. As an example, we found that one of the most famous encryption libraries - Bouncy Castle - in our opinion struggles to be called well maintained or simple because it has become very large and complex. They have incorporated all possible algorithms for all possible uses, and have ended with bloated source and a complex API. Inspecting this code is problematic, using it properly is fraught with danger.

Instead, after exhaustive testing, we found two leaders - libsodium and inferno. The second was our preferred option, but did not meet portability requirements. Denote have therefore settled on the use of libsodium. To be clear - all of these libraries implement all of our required encryption primitives, but libsodium does it with the simplest interface and reducing the chance of unintended errors.

Simplicity

Complexity is the enemy of correctness. In all design decisions, the Denote development teams have focused their decisions on simplicity, security, privacy as prime drivers.

With simplicity comes easy of inspection and correction - which are essential processes in creating solid software.

Encryption In Denote

What Encryption Is Used

Denote uses industry standard libraries and procedures to manage keys and encryption of data. This section will explain the process that is undertaken to set up the secure environment to store your data. The headline algorithms chosen are:

AEAD Authenticated Encryption with Additional Data - which are forms of encryption that ensure confidentiality and authenticity by including a small amount of extra data, tying the encryption to a context and also providing validation that encrypted data is unchanged.

XChaCha20-Poly1305 - ChaCha20 is an encryption algorithm - specifically a stream cipher - developed in 2008 by Dan Bernstein and widely used, including being supported in TLS as a recommended Cipher Suite since TLS1.3 under the IANA name TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256. It has been throughly tested and provides good performance advantages over AES, and is especially useful for mobile devices. We have elected to use the XChaCha20 variant as defined by the IETF because it provides better IV (Initialization Vector) management - specifically support for large stateless random IVs rather than stateful sequenced IVs, as required by ChaCha20. Poly1305 provides Message Authentication (data integrity and authenticity) for AEAD - meaning it takes your encrypted data and some other information and produces a code that can be checked at decryption time to prove the message was unchanged, and that it did get created in our app running under your account.

EC25519 - A Public/Private key system using elliptic curve providing fast and secure key sharing for sending messages to other users. These messages contain requests like "share book" and "unshare book", and can only be unpackaged by the recipient of the message.

Argon2 - is a key derivation function (means it creates strong encryption keys from passphrase and salts) with both memory and compute time hardness. It was selected as the winner of the 2015 Password Hashing Competition and provides protection against both software and hardware-optimised crackers. We use Argon2 in Hybrid mode ("Argon2id") with the following values: Lanes=4, HashLen=16, SaltLen=16, TimeCost=1, MemoryCost=8MB, guided by recommendations in RFC9106, but for memory restricted applications. While Argon2 is slightly younger than other algorithms we have chosen, it has been thoroughly vetted as part of the competition, and due to its high profile it has attracted a large number of researchers who have continued to prod and poke for vulnerabilities.

In summary - all books, notes, sections, and personal information is encrypted using XChaCha20-Poly1305. Sharing a book with another user uses EC25519 and Diffie Hellman key exchange to swap symmetric encryption keys. Your passphrase is converted into an encryption key and server password using Argon2 key stretching with separate random salts.

The Process Of Protecting Your Data

Your first interaction with Denote's Encryption will be after installing the application - you are asked to enter a new passphrase. This passphrase is used to generate two very important pieces of information - your encryption password and your cloud password. Your ID is randomly chosen using a cryptographically strong source of randomness. You only need to know this ID if you intend to start sharing books or install the application on another device to start syncing.

Encryption Password
We create chunk of random data (called a salt) and use that with your passphrase to generate your encryption key by a process called Key Stretching using Argon2. The salt is saved but the key is not. Decrypting your data when you start the app requires both your passphrase (from you) and your salt (saved by the app) when you log in to the app. We never save your encryption key anywhere (unless you ask us to save it in the device's secure enclave for passwordless application startup), and it is impossible to calculate your encryption key knowing only the salt or only having access to the encrypted data.

Cloud Password
We also create a Cloud Password using the same process (Argon2 based Key Stretching) but with a different salt. This identifies you to our servers - it tells us that the user at the device connecting has the correct passphrase, but it doesn't tell us what the passphrase is!

Note that our servers knowing your cloud password and authenticating you does not mean we can decrypt your data because we don't have your passphrase or your encryption key. It is also impossible to reverse the Key Stretching algorithm to calculate your passphrase, and to get your encryption key that way.

Generating Encryption Key and Cloud Password

Private/Public Key
Lastly we create an Elliptic Curve public/private key pair at random using the curve 25519 (again, with a cryptographically strong source of randomness). This is used to establish secret keys for sharing information with other people. Your public key is stored in the cloud and can be shared with anyone, but your private key remains your control, encrypted.

Encrypting Data
When we need to encrypt some data, we use your encryption key, another chunk of random data (the nonce), and a some Additional Authentication Data (some context based information) to encrypt your data using the XChaCha20-Poly1305 algorithm. Every encryption operation uses a different nonce, so even if we are encrypting two identical books or notes, the encrypted results will always be different. The nonce is stored with the encrypted data. After every decryption operation, we verify that the data wasn't somehow modified (one of the features of AEAD) and therefore that the Additional Authentication Data is correct, and the decryption was successful.

Encrypting and Decrypting Notes, Books etc

Every book you create has a completely different and random (i.e. strong) encryption key, and all the sections and notes within that book are encrypted with that book's key. The keys for your books are encrypted with your encryption key and stored locally.

If you subscribe, then your data can be also stored in the cloud and automatically synced with other devices. This data is always encrypted with your key and cannot be read away from your devices. To be clear, Denote staff cannot read your data, and there is no way to recover your data should you lose your passphrase. All of your data appears as random bytes to anyone else.

Sharing A Book
If you then decide to share a book with a friend (e.g. to collaborate on it), we use your private key and their public key to create a shared key (via the Diffie-Hellman Key Exchange using Elliptic Curve 25519). This shared key is used to encrypt a message for their eyes only that is cryptographically signed by you - meaning that only they can read it, and it could only have come from you. That message contains book details and the book encryption key.

Sharing Books

Every book has a different encryption key, so you can share that book key with another user without putting any other book at risk of exposure.

Can a person steal your book?
For a person to be able to steal your book, they will need (at least):

In other words, without your passphrase and significant amounts of other supporting information (salts, book identities, books keys), it is impossible for a third person can access your data.

All of the operations above are happening in the background and completely invisible to you. But you can rest assured that your data is safe from prying eyes.