02

The Vault

What makes the SoJourn framework different from a typical cloud note-taking application is that the Vault, which uses Shamir’s Secret Sharing to save a series of values to many IPFS locations. This eliminates the chance of a central cloud admin accessing a whole encrypted file and breaking its encryption. An attacker in this scheme would have to know which IPFS addresses correspond to the user’s data, and would still need the user’s private key to decrypt the file.

This is “belt-and-suspenders” security for users that are willing to trade some of the benefits of “Google Docs” style cloud apps for a high level of assurance that cloud storage will not result in the potential for a bad actor at a cloud company to find, access, decypher or hand over data.

Vault Procedure

Encrypt the Notes

We use AES to encrypt the data during the Done function in the application.

AES requires an input of a 256 bit private key. The devKit demonstrates this by generating a private key.

The entire purpose of the vault is to allow a user to access their data from other devices. In order to do that, they need to be able to share their private keys with other devices safetly. We did not implement that in the dev kit, but there are a few options. Each one effects the user experience in different ways. One way is to generate the key using a menomonic. This would force a user to keep track of a 12 word phrase. The pros of this is that it is a simple solution, the con is that uPort and other wallets use mnemonics, and it might be hard to keep track of multiple. Another solution is to use Integrated Encryption Scheme , a variation on Diffie Hellman, to securely share a private key with other devices. Yet another solution is to use a QR code to pass the private key between devices.

Grind the Notes into Little Bits

There’s a lot of history that you can learn about Adi Shamir and his secret sharing algorithm (SSSA), which we decided to use for this pattern. But for the purposes of this devKit, here are the essentials:

We needed a way to split up a file in such a way that there is no way to gain any information about the original content from any single piece, even if decrypted. In fact, the pieces should be useless without all the necessary segments together. SSSA does this and turns out to have other unexpectedly useful benefits, like better redundancy and quicker file reassembly, and that should give developers a lot of options for cool user features.

The key terms you need to know to work with this module are:

SECRET

For SSSA, the Secret is simply any bit array, but we implemented the Secret specifically as a Base64-encoded string, so that SSSA can process the AES Encrypted file that we are passing it.

SHARES

We won’t get into polynomials and how SSSA does its magic. But you need to know that the generateShares() function returns a set of hex values which, through combine() allow you to reconstruct the original data IF you have all the shares together to pass into that function.

THRESHOLD

Saving Shares to decentralized storage involves the risk that some of the storage locations may not be available at any given time. If your Threshold value is set to the same number as Shares, you will need to be able to pull every Share successfully in order to reconstruct the file. On the other hand, if you set the Threshold value to 1, you would only need one of the Shares to reconstruct the file. That would kind of defeat the purpose of this whole bag of tricks, but you could do it. In a production application, it’s up to you to decide the optimal ratio of Threshold to total Shares, for redundancy.

Storing the Shares

Once you have the data sliced up in to the Shares, they need to be stored somewhere. On this implementation, we chose to use IPFS via the Infura Gateway.

Infura stores data on many AWS instances distributed globally. It should be noted that currently Infura is managing this in a somewhat centralized way, but Infura plans to run IPFS fully decentralized, so consider this a proof of concept...and it may be good enough for many users’ privacy requirements.

IPFS stores data by hashing the content and using that hash as the address to access the data. You can then use the hash to enable any browser to pull up the data at that location. In short, all IPFS locations are accessible to the public. That sounds like the opposite of privacy, perhaps, but thanks to the previous step of splitting the data into Shares, the probability of an attacker finding the correct set of Shares to reconstruct the file is astronomically small. Pretty cool, yeah?

Storing the secret locations to find the Shares

If the user can’t supply the locations of a Threshold number of Shares to their data, the data is as good as gone. They will never find it out there in IPFS. So it is critical that your app store the file locations somewhere in a secure way, so that the user can use it to restore their data. It should also be stored away from the user’s private key for AES, so that an attacker would have to gain access to two separate resources in order to both reconstruct and decrypt the file.

IPFS returns a hash of each Share location, and the code will concatenate the hashes into an array, which, depending on how your application manages this, you will use to let the user restore their data (e.g., in the event of them losing their phone).