Encryption - Part 2

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

 

Treesystem Encryption

ZeroDark.cloud provides a treesystem in the cloud. So when you interact with the client framework, you get to store nodes in a hierarchy and every node has a name:

                  (documents)
                   /      \
              (foobar)    (recipes)
                            |
               (the secret coca-cola formula.txt)

ZeroDark considers node names to be sensitive information, and is architected to ensure zero-knowledge of node names. We (the ZeroDark team) cannot read the cleartext names of any nodes. So, for example, the treesystem path:

  • /documents/recipes/the secret coca-cola formula.txt

The server cannot read any of the following names:

  • documents
  • recipes
  • the secret coca-cola formula.txt

All of these names get hashed and encrypted to ensure that only those with read-permission for the node can actually read the name of the node.

 

Encrypted Node Names

Here's how it works:

  • Every node has a randomly generated "dirSalt" (160 bits of entropy)
  • The cleartext node-name is hashed with the dirSalt of its parent node
  • The hashed result is 160 bits, encoded using zBase32

The end result is that the server sees something like this:

                 (3h9kxxjypxgrzqmd88qju1sh5u1nudxw)
                       /                     \
(qdiqqne5i8oddw95q6dgerfa7jbbgkoo)(54nb157pg5m7bioqptm41zye3shuyrgw)
                                                   |
                                  (g5jqnkmrkrsjpm9atow31sz3aeprkioj)

The cleartext node-name is encrypted using the file's encryption key (see part 1 for details), and gets stored in the RCRD file:

{
    "fileID": "E21E04505CD4430EBBBB989E92CE90BF",
    "keys": {
        "UID:z55tqmfr9kix1p1gntotqpwkacpuoyno": {
            "perms": "rws",
            "key": "eyJ2ZXJzaW9uIjoxLCJlbmNvZGluZyI6IkN1cnZlNDE0MTciLCJrZXlJRCI6InlLcVl3U2dzL2drUTRSTVlsME9wYVE9PSIsImtleVN1aXRlIjoiVGhyZWVGaXNoLTUxMiIsIm1hYyI6IjV4ZEZCMEprNjVvPSIsImVuY3J5cHRlZCI6Ik1JSEVCZ2xnaGtnQlpRTUVBZ01FZFRCekF3SUhBQUlCTkFJMEdxSDN3Q3hNdDRWaGp6MS9aaFZrbmk4WGtQWTFUMFp4SlZrZytJZEgra1pBNHl1bFZadER2cC9yUlIvUlRtRUZ0K2JjUEFJMElFenFMeVA5RmpoNXRmZnNxa1AraDNSNlVuZmxpZnVDQVgyU291L0R1eGRncFU0L2RyelNkN0lrZUp3WGV1Z0dXNWhBM1FSQUQrYkhSTFhtbzk3eTB3Y1MrOUtmUnZ5dm55M1MxYUNlZmRzNWk4M1lEWE8rbW00WmdpSU1TbDhncnM2andPMVVOajQwZjZ4MW9ZVC9pTStzMUdRc3hRPT0ifQ=="
        }
    },
  "metadata": "zL9FiZFl5Pbo4NXQkrWanA6yWI0B4QTdYSKISnqAsKfX38Kwd2/KNE0bOTysRk9wXq0XKswWPaxEtv0OVuf4MLaZubQTQPTvCt4k4J1/K9Et1pWuYZjOS7uKvZrwQ9rsVLNh9Ne6lJjeQ5Rny+CrI4HM6pI="
  ...
}

In this example, only a single user is given permission to read the node. (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. The file encryption key can then be used to decrypt the metadata section. Which will reveal the node name. For example: "the secret coca-cola formula.txt"

Notes
  • Just as you might expect, you cannot store 2 nodes with the same name in the same "folder". The hashes would collide.

  • Since every node has a different "dirSalt", this means that 2 nodes with the same name, but different parents (different "folders") would have different hashes.

 

Treesystem Access

All data is stored in S3. And every user gets their own S3 bucket.

Only a bucket's owner is allowed to list the contents of their bucket. For example, Alice can list every item in her bucket. However, Bob is NEVER allowed to perform this action on Alice's bucket.

Alice can give Bob access to particular nodes in her treesystem. For example, if Alice chooses to give Bob access to /foo, then Bob would be able to ask the system to list children of that node, which would reveal /foo/bar.

Note that, due to hashing & dirSalt, it's effectively impossible to guess the location of files. For example, imagine I told you the following information:

  • My Bitcoin private key is stored in my bucket
  • The bucket name is com.4th-a.user.z55tqmfr9kix1p1gntotqpwkacpuoyno-e0975e8e
  • It has "lots of money" (i.e. you're super motivated to hack me now)
  • It's in the root folder of my Storm4 account
  • The cleartext name is bitcoinPrivateKey.txt

However, you still don't know:

  • the dirSalt
  • the hashedNodeName

Which means there are 160 bits of entropy separating you from the actual S3 keypath. That's 2^160 possible filenames. Good luck. Of course, that's not even the end of the story. Even if I handed you the S3 keypath, you would only receive an encrypted file. The content is encrypted using Threefish-512, with a randomly generated 512 bit key. You'd have to break that too.

ZeroDark.cloud gives you to tools to provide this same level of security & privacy for your customers.

 

Summary

ZeroDark.cloud was architected from the ground up to provide a usable zero-knowledge sync & messaging system. Designed by veterans in the security world, we've seen too many "solutions" where security was either added in as an after-thought (and thus leaked too much information), or it was architected to be so "secure", it ended up being unusable. In contrast, ZeroDark.cloud servers know the absolute minimum possible to implement a usable system:

  • who owns the file (i.e. who's paying for it)
  • who was write permission (so server can enforce it)
  • who needs to be notified of changes (push notifications are not optional today)

 

Next Step

You now understand the fundamentals — how ZeroDark encrypts data, and provides zero-knowledge in the cloud. If you want to learn more:

  • learn how to audit your cloud data
  • learn where to set breakpoints in the framework to audit the client-side cryptography
  • learn how ZeroDark sandboxes separate apps using per-app encryption
  • get super technical, and read the cryptographic details