Skip to content

Latest commit

 

History

History
212 lines (144 loc) · 9.11 KB

File metadata and controls

212 lines (144 loc) · 9.11 KB

Security Architecture

Virtual Filesystem

Cryptomator provides a virtual drive. Add, edit, remove files as you're used to with just any disk drive.

Files are transparently en- and decrypted. There are no unencrypted copies on your hard disk drive. With every access on your files inside the virtual drive, Cryptomator will en- and decrypt these files on-the-fly.

Currently WinFsp (on Windows) and macFUSE (on macOS) and FUSE (Linux) are our frontends of choice. If they're not available on your system, Cryptomator will fall back on WebDAV, as it is supported on every major operating system. WebDAV is an HTTP-based protocol and Cryptomator acts as a WebDAV server accepting so-called loopback connections on your local machine only.

Whenever your file manager accesses files through this virtual drive, Cryptomator will process this request via the following layers.

Vault Configuration

Every vault must have a vault configuration file named vault.cryptomator in the root directory of the vault. It is a JWT containing basic information about the vault and specification what key to use. The JWT is signed using the 512 bit raw masterkey.

This is an example of an encoded vault configuration file:

eyJraWQiOiJtYXN0ZXJrZXlmaWxlOm1hc3RlcmtleS5jcnlwdG9tYXRvciIsInR5cCI6IkpXVCIsImFsZyI6IkhTMjU2In0.eyJmb3JtYXQiOjgsInNob3J0ZW5pbmdUaHJlc2hvbGQiOjIyMCwianRpIjoiY2U5NzZmN2EtN2I5Mi00Y2MwLWI0YzEtYzc0YTZhYTE3Y2Y1IiwiY2lwaGVyQ29tYm8iOiJTSVZfQ1RSTUFDIn0.IJlu4dHb3fqB2fAk9lf8G8zyEXc7OLB-5m9aNxOEXIQ

The decoded header:

{
  "kid": "masterkeyfile:masterkey.cryptomator", /* URI of where to get the key */
  "typ": "JWT",
  "alg": "HS256" /* current implementations also support HS384 and HS512 */
}

The decoded payload:

{
  "format": 8, /* vault format for checking software compatibility */
  "shorteningThreshold": 220, /* how many characters in ciphertext filenames before shortening */
  "jti": "ce976f7a-7b92-4cc0-b4c1-c74a6aa17cf5", /* random UUID to uniquely identify the vault */
  "cipherCombo": "SIV_GCM" /* mode of operation for the block cipher. Other possible values are "SIV_CTRMAC" */
}

When opening a vault, the following steps have to be followed:

  1. Decode vault.cryptomator without verification.
  2. Read kid header and, depending on its value, retrieve the masterkey from the specified location.
  3. Verify the JWT signature using the masterkey.
  4. Make sure format and cipherCombo are supported.

Masterkey

Each vault has its own 256 bit encryption as well as MAC masterkey used for encryption of file specific keys and file authentication, respectively.

All key material is generated by a :abbr:`CSPRNG (Cryptographically secure pseudorandom number generator)`.

These keys are themselves protected and can be retrieved using, either of the following methods, depending on the use case:

Using Cryptomator Hub

When using :ref:`Cryptomator Hub <hub/access-vault/unlocking-a-vault>`, the encrypted raw masterkey can be retrieved from a the server component.

Note

If a vault is managed by Cryptomator Hub, the vault.cryptomator's kid field will point to the resource URI of said vault on the corresponding Hub instance, prefixed by hub+.

Example: "kid": "hub+https://hub.example.com/api/vaults/bb36d67c"

Every Cryptomator Hub user who is authorized to access this vault will retrieve an individual ciphertext from the vault's /access-token sub-resource. This ciphertext is formatted as a JWE and can be decrypted using ECDH-ES and the :ref:`user's static private key <security/hub/keys/user-keys>`. The JWE's decoded header looks something like this:

{
    "alg": "ECDH-ES",
    "enc": "A256GCM",
    "epk": {
        "crv": "P-384",
        "kty": "EC",
        "x": "p1J...g",
        "y": "8Il...H"
    }
    "apu": "",
    "apv": ""
}

The JWE's decrypted payload holds a single value, which can then be consumed by Cryptomator to unlock the vault:

{
    "key": "H7u...o==" /* 512 bit raw masterkey */
}

Masterkey File

Alternatively, for normal password-protected vaults, Cryptomator will derive a :abbr:`KEK (Key-encryption key)` via scrypt, encrypt the masterkeys using AES Key Wrap (RFC 3394), and store the results together with the key derivation parameters in a JSON file:

encryptionMasterKey := createRandomBytes(32)
macMasterKey := createRandomBytes(32)
kek := scrypt(password, scryptSalt, scryptCostParam, scryptBlockSize)
wrappedEncryptionMasterKey := aesKeyWrap(encryptionMasterKey, kek)
wrappedMacMasterKey := aesKeyWrap(macMasterKey, kek)

KEK Derivation

The wrapped keys and the parameters needed to derive the KEK are then stored as integers or Base64-encoded strings in a JSON file named masterkey.cryptomator, which is located in the root directory of the vault.

{
    "version": 999, /* deprecated, vault format is now specified in the vault configuration */
    "scryptSalt": "QGk...jY=",
    "scryptCostParam": 16384,
    "scryptBlockSize": 8,
    "primaryMasterKey": "QDi...Q==", /* wrappedEncryptionMasterKey */
    "hmacMasterKey": "L83...Q==", /* wrappedMacMasterKey */
    "versionMac": "3/U...9Q=" /* HMAC-256 of vault version to prevent undetected downgrade attacks */
}

When unlocking a vault the KEK is used to unwrap (i.e. decrypt) the stored masterkeys.

Masterkey Decryption

Key Rotation: Multiple Masterkey Generations using Cryptomator Hub with Universal Vault Format

Unified Vault Format (uvf) defines a common vendor-independent standard based on Vault Format 8.

The uvf metadata file vault.uvf replaces the vault.cryptomator file. It is both stored in the vault as file and uploaded to hub. It can contain many key generations - only the latest generation is used for data encryption. The older generations are used to read the older data encrypted with previous generation keys. See :ref:`Key Rotation <security/uvf/key-rotation>` for more details.

Cryptomator hub 1.3.0) introduced user-specific vault access token JWE containing the vault masterkey for data encryption. In the uvf setting, the uvf metadata (with the current and older (master)key generations.

Instead, it will contain a Vault Member key, which allows to decrypt the vault.uvf metadata. Specifically, a Vault Owner will have an access token under /access-token sub-resource of the form

{
    "key": "{memberkey}",
    "recoveryKey": "{recovery key}",
}

Non-owner Vault Members will not have the recoveryKey shared with them, the JWE will only contain the key element. Vault members can decrypt their access token using their private user key. See :ref:`User Key Pair <security/hub/keys/user-keys>`.

Upon Vault creation, a new memberkey and an asymmetric recovery key pair are generated. The public recovery key and the vault.uvf JWE are uploaded to Cryptomator hub.

uvf Vault Creation

See :ref:`Key Rotation <security/uvf/key-rotation>` for more details on key rotation and vault.uvf.

Vault sharing is the same as with access tokens introduced in Cryptomator hub 1.3.0.

Only the payload's key field contains the latest member key (instead of the masterkey) and the recoverKey (Vault Owners only).

uvf Vault Sharing