Encryption - Part 1

  • Part 1 - File encryption
  • Part 2 - Treesystem encryption
  • Part 3 - Per-app encryption
  • Part 4 - Cryptographic details for experts

 

Overview

All data stored in the cloud is encrypted using keys that are unknown to the ZeroDark server. This means the server (or ZeroDark team) cannot decrypt the cloud content. This is what is meant by zero-knowledge.

You can think of it like this. There are 3 parties involved:

  • the user
  • you — the developer / business using the framework
  • us — the ZeroDark team

We (the ZeroDark team) are not able to read any of the content generated by your app. You (the developer) have control over who can read what content. And the framework enforces your decisions using cryptography. Thus any individual file in the cloud can only be decrypted by the parties you specified.

You can code your app in many different ways, for many different circumstances. For example:

  • Only Alice is able to read her data
  • Only Alice & Bob can read the data
  • Only Alice + members of her team
  • Only Alice + the root hospital key (e.g. to comply with industry regulations)
  • Only Alice + your server

You control access on a per-file basis, and can write code as needed for your situation.

Old-fashioned & outdated systems attempt to control access to data via a gatekeeper. You tell the gatekeeper who has access, and then you trust the gatekeeper to enforce those permissions. ZeroDark is the next evolution of security. Permissions are controlled via modern cryptography. You determine who has access, and the framework enforces those permissions using state-of-the-art encryption (not fragile gatekeepers).

 

Public/Private Key Pairs

It starts with public/private key pairs. All users in ZeroDark.cloud generate a public/private key pair. This pair is generated on the client's device, and the client is the only one who knows the private key. The ZeroDark server does NOT know the private keys of users.

 

Public Keys are verified via Ethereum Smart Contract

Public keys are hosted in the cloud, and can easily be downloaded by anyone.

ZeroDark.cloud uses the Ethereum Blockchain to secure public keys, and protect against the man-in-the-middle attack.

The man-in-the-middle attack (in brief):

If Alice downloads Bob's public key from a server, how can she be sure it's really Bob's public key ? That is, how can she be sure the server hasn't been compromised, and that Bob's public key has actually been replaced by somebody looking to eavesdrop on Bob's conversations ?

ZeroDark.cloud uses an Ethereum Smart Contract to solve this problem. Using the ethereum blockchain, one can now deploy small computer programs that cannot be modified. That is, the source code cannot be modified or upgraded in any way.

(You read that correctly - zero changes can be made to the code once it's deployed to Ethereum. That's why they call it a "contract".)

Once deployed, the smart contract can be interacted with via any ethereum node in the world. So we wrote and deployed a smart contract that:

  • allows the public key information for a user to be stored in the contract
  • allows this information to be written once and ONLY once

This effectively acts as a trusted 3rd party because:

  • The source code doesn't allow the public key information to be tampered with
  • The Ethereum Blockchain doesn't allow the source code to be tampered with

For detailed information about how the smart contract works, see the Ethereum article.

 

File Encryption

Every file uploaded to the cloud gets encrypted with a different randomly generated 512-bit key. This is called the file encryption key.

Clients control read-permissions with cryptography

Since all files are encrypted with a different file encryption key, the ability to read a file is controlled by the abililty to access the file encryption key. Clients control this by selectively "wrapping" the file encryption key with the public keys of those who are given read-permission.

The term "wrapping" means to take keyA, and encrypt it using keyB. In this case, the client is taking the file encryption key, and wrapping it using a public key. Therefore, to unwrap the file encryption key will require the corresponding private key.

Here's a real-world example (taken from an actual cloud file):

{
    "fileID": "E21E04505CD4430EBBBB989E92CE90BF",
    "keys": {
        "UID:z55tqmfr9kix1p1gntotqpwkacpuoyno": {
            "perms": "rws",
            "key": "eyJ2ZXJzaW9uIjoxLCJlbmNvZGluZyI6IkN1cnZlNDE0MTciLCJrZXlJRCI6InlLcVl3U2dzL2drUTRSTVlsME9wYVE9PSIsImtleVN1aXRlIjoiVGhyZWVGaXNoLTUxMiIsIm1hYyI6IjV4ZEZCMEprNjVvPSIsImVuY3J5cHRlZCI6Ik1JSEVCZ2xnaGtnQlpRTUVBZ01FZFRCekF3SUhBQUlCTkFJMEdxSDN3Q3hNdDRWaGp6MS9aaFZrbmk4WGtQWTFUMFp4SlZrZytJZEgra1pBNHl1bFZadER2cC9yUlIvUlRtRUZ0K2JjUEFJMElFenFMeVA5RmpoNXRmZnNxa1AraDNSNlVuZmxpZnVDQVgyU291L0R1eGRncFU0L2RyelNkN0lrZUp3WGV1Z0dXNWhBM1FSQUQrYkhSTFhtbzk3eTB3Y1MrOUtmUnZ5dm55M1MxYUNlZmRzNWk4M1lEWE8rbW00WmdpSU1TbDhncnM2andPMVVOajQwZjZ4MW9ZVC9pTStzMUdRc3hRPT0ifQ=="
        }
    },
    ...
}

In this example, only a single user is given permission to read the file. (userID: z55tqm...) So this user will need to use their private key to decrypt the key blob ("eyJ2ZXJ..."), which will reveal the file encryption key. And the file encryption key can then be used to decrypt the corresponding file.

To add additional permissions, the client simply adds another item to the "keys" section. This scales easily for small to medium group sizes. For larger numbers, a groups feature is used, which is discussed elsewhere.

The process can be visualized like this:

// If we're granting read permission to Alice & Bob

(cleartext file) (file encryption key)---------->(wrap)
          \         /                             /  \
      (Threefish-512 TBC)           (alice's pubKey) (bob's pubKey)
              |                           |                |
      (encrypted file)             (wrapped file key) (wrapped file key)
                                                 \       /
                                             (JSON record file)

This generates 2 files:

  1. The encrypted file is called the data file. It will end up getting stored in the cloud with a name like 58fidhxeyyfzgp73hgefpr956jaxa6xs.data.
  2. The JSON file is called the record file. It will end up getting stored in the cloud with a name like 58fidhxeyyfzgp73hgefpr956jaxa6xs.rcrd.

 

Next Step

Now you're ready for part 2: Treesystem encryption