Cryptocat uses a Double Ratchet-based encryption protocol that combines a forward-secure ratchet with a zero round-trip authenticated key exchange. As a transport layer for encrypted messages, Cryptocat adopts the OMEMO Multi-End Message and Object Encryption standard, which also gives Cryptocat multi-device support and allows for offline messaging. In terms of the transport layer, Cryptocat uses XMPP over a long-standing, TLS-encrypted WebSockets connection.
Every Cryptocat device owns a long-term identityKey pair which helps with the establishment of the initial authenticated key exchange. This key pair also serves to sign the device's signedPreKey, an ephemeral public key that also is mixed into the authenticated key exchange. The signedPreKey is also shipped with 100, unsigned, one-time-use preKeys, and is regenerated and re-signed every week.
Suppose Alice wanted to start a new session with Bob. Alice would then fetch Bob's current signedPreKey and his list of 100 preKeys from the Cryptocat network. Alice would then select a random preKey from the list. Alice then generates her own initKey pair, which is a keypair used only for the purposes of initializing a new session. Alice then performs the following computation in order to obtain the initial session secret S:
S = SHA256(
X25519(AliceIdentityKey, BobSignedPreKey) ||
X25519(AliceInitKey, BobIdentityKey) ||
X25519(AliceInitKey, BobSignedPreKey) ||
) = HKDF(S, Constant1, Constant2)
Between messages, Cryptocat maintains a forward-secure ratcheting chain that creates a new ephemeral key pair for each message, and derives their chain of authenticity by mixing in a chain going back to S via a Hash-Based Key Derivation Function (HKDF). Here is an example occuring later in the conversation, after Bob had also derived a BobMessageEphemeralKey and other session state elements:
AliceMessageEphemeralKey = X25519_NewKeyPair()
AliceSharedKey = X25519(
) = HKDF(S, AliceReceivingRootKey, Constant2)
AliceMessageEncryptionKey = HKDF(
) = AESGCM256(
Alice then sends (AliceMessageEphemeralKeyPublic, AliceEncryptedMessage, AliceEncryptedMessageTag).
Constant1, Constant2 and Constant3 are some publicly known constant strings coded into the protocol implementation.
- AES is used in Galois Counter Mode (GCM) for authenticated symmetric encryption with added data.
- X25519 is used for all Elliptic-Curve Diffie-Hellman (ECDH) operations. A four-way ECDH handshake is used for the initial authenticated key exchange and further ECDH operations are routinely performed for preKey generation and message ratcheting.
- ED25519 is used for generating the identityKey pair and for signing and verifying the signedPreKey, but is otherwise unused throughout the protocol.
- SHA256 is used as the standard hashing function and as the underlying hash function for the HKDF.
Cryptocat makes the following assumptions:
- Untrusted network: We assume that an attacker controls the network and so can intercept, tamper with and inject network messages.
- Long-term key compromise: We assume that an attacker may at some point compromise the long-term identityKey pair of a participant.
Given our threat model, Cryptocat aims to accomplish the following security goals:
- Secrecy: A message sent between buddies can only be decrypted between these buddies.
- Authenticity: If Alice receive an apparently valid message from Bob, then Bob must have sent this message to Alice.
- Indistinguishability: If Alice randomly chooses between two messages of the same size and sends only one to Bob, an attacker cannot determine which message was sent.
- Forward secrecy: If Alice sends a message to Bob and Alice's key state at the time of this message is subsequently compromised, all previous messages retain their Secrecy property.
- Future secrecy: If Alice sends a first message to Bob, receives a reply from Bob, and then sends a second message to Bob, Alice's second message remains secret even if her key state for the first message is compromised.
Cryptocat offers users the ability to verify the authenticity of their buddies' devices. In that way, they can ensure that a malicious party (including, potentially, the Cryptocat network itself) is not masquerading as the device of another individual. Device fingeprints are calculated thus:
DeviceFingerprint = SHA256( deviceId || SHA256( username || deviceName || deviceIcon ) || deviceIdentityKeyPublic ).HexString().First32Characters()
In the above example, deviceId is a random 32-byte device identifier that is generated upon device registration and that never changes. deviceName is a name that the user assigns to the device that also cannot be later modified. deviceIcon is one of three icons (0, representing a laptop, 1, representing an all-in-one desktop and 2, representing a PC) and also cannot be modified.
Cryptocat software provides users with the ability to share documents, video recordings, photos and other such media. These are all threated as the same type of plaintext (a "file") and are all handled as follows:
- A 256-bit AES-GCM fileKey is randomly chosen and used to symmetrically encrypt the file.
- The encrypted file is then uploaded to a Cryptocat server where it is stored for 30 days. The Cryptocat server obtains the encrypted file and is able to determine its size, but is nevertheless not able to determine anything else about the file, including its type or file name.
- The sender then sends the fileKey and its corresponding AES-GCM fileNonce, fileTag to the recipient along with a fileUrl pointer to where the encrypted file can be fetched from the Cryptocat network and a fileName value indicating the name of the file. This information is communicated a specially formatted, but nevertheless regularly encrypted Cryptocat chat message.
- The recipient's client parses the chat message as one that is pointing to a file, downloads the ciphertext from fileUrl, decrypts it with fileKey and fileNonce and authenticates it with fileTag.
- If decryption and authentication are successful, the file is presented to the recipient for viewing or download, depending on what is appropriate for the file type.
Note that fileUrl cannot be just any HTTP URI but is specially restricted for the purposes of Cryptocat file sharing.
Miscellaneous Security Features
Aside of the message encryption protocol, Cryptocat adopts the following security features in order to provide a generally more robust experience across the client:
- Authenticated installers: Cryptocat client installation packages are authenticated using Authenticode on Windows, gpg2 on Linux and Apple code signing on Mac.
- Signed updates: In addition to installer authentication, Cryptocat's built-in update downloader will run an independent signature verification on all downloads.
- Certificate pinning: Cryptocat will check for a "known-good" TLS certificate before initiating a connection to the Cryptocat XMPP server.
- Device management: Users are given the option of independently verifying their buddies' device lists and are notified when a buddy's device list is modified.
Reporting Security Issues
Note: a Bug Bounty Program is currently in effect.
Cryptocat is written with security in mind and uses state-of-the-art cryptography engineering to protect your privacy. However, in the event that a security vulnerability is discovered, the project operates under the principle of full disclosure. If you discover a critical security issue with Cryptocat software, report it. You will be helping safeguard the privacy of thousands of people. Depending on the severity of the issue, here is how we recommend you report your findings:
- Critical or High Severity: Send a message to nadim on Cryptocat at least one week before publishing your findings. You retain full right (and our explicit support) to publish your findings, but we ask for a window to push a fix to our users beforehand.
- Medium or Low Severity: Open a ticket on the GitHub issue tracker documenting the issue.
Bug Bounty Program
From December 20, 2016 and until December 31, 2017, Cryptocat is holding a Bug Bounty Program. The goal of this program is to invite independent analysis of Cryptocat's security, especially since its complete rewrite which was completed in April 2016.
Bug Bountry Program Prize
- $500 USD delivered via PayPal.
- A good book from Amazon.com chosen by us.
- Recognition on the Cryptocat website.
- A personal thank-you note.
Due to Cryptocat's limited funding as volunteer-run software, the bounty is held in a "contest" style: the first person to report a vulnerability will receive the prize, and the Bug Bounty Program will then be closed until further notice. Should we receive more than one bounty report simultaneously, we will award the prize to the report we judge to be more important.
However: Should you win the Bug Bounty Program prize but forfeit the $500 USD prize money, the Bug Bounty Program will remain open for a second potential winner, and you will still receive the other three elements of the prize.
Bug Bounty Program Criteria
- Your report must be submitted before December 31, 2017 (anywhere on Earth).
- A proof-of-concept must be included.
- You must be agree with full public disclosure of the bug you have discovered. You may choose to forfeit public credit.
Your reported vulnerability must be, within reasonable judgement, a high-to-critical severity vulnerability. For example, it must allow remote account compromise, user or device impersonation, message decryption, arbirtrary code execution, or something along these lines. A simple denial of service, to give a counter-example, or a bug that is reliant on pre-existing control of the victim's device, is not eligible. We promise to be fair regarding the severity of your reported bug.
Any submitted report must involve a bug that is exploitable in the latest version of Cryptocat at the time of submission.
Bug Bounty Program Report Submission
Simply send a Cryptocat message to nadim on Cryptocat in order to submit your report. It's the personal account of the person responsible for writing the software.
Thank you for helping make Cryptocat safer for everyone. Good luck!