LeastAuthority / S4-2.0

Simple Secure Storage Service 2.0
Apache License 2.0
7 stars 1 forks source link

Secure the Zcash wallet #3

Closed exarkun closed 5 years ago

exarkun commented 6 years ago

Investigate how to run the Zcash full node with only the incoming viewing key (or does it need the full viewing key? What is the difference?). Specifically, it should run without the spending key so that if it is compromised funds cannot be transferred away.

Since the node will be deployed for #1 , a brand new wallet / new keys should be generated here and the old wallet / keys discarded (drained of funds first, if necessary) since they will not necessarily have been deployed in a way that keeps them safe from compromise.

Ideally the payment address would be a multisig address. However, Zcash does not yet support multisig shielded addresses. A fallback might be to manually apply Shamir's Secret Sharing to the spending key (from which all other keys are derived) and distribute the pieces accordingly. This introduces operational complexity and requires some kind of trusted set up and distribution, though.

exarkun commented 5 years ago

Since the node will be deployed for #1 , a brand new wallet / new keys should be generated here and the old wallet / keys discarded (drained of funds first, if necessary) since they will not necessarily have been deployed in a way that keeps them safe from compromise.

So far I've been doing this pretty regularly anyway. Deploy the service from scratch, tweak the configuration, maybe update the deployment, maybe destroy it and re-deploy it from scratch, repeat.

exarkun commented 5 years ago

Basically, this issue implies the need to have a secrets management workflow. For this specific issue, we need to give Zcash a wallet (let's say this is a viewing key/incoming viewing key). The attacks that can be performed to compromise this wallet are something like:

  1. Someone steals the hard drive and reads the wallet from it.
  2. Someone freezes the computer, boots into another OS, and reads the wallet from the frozen memory from the previous boot.
  3. Someone intercepts the key in transit between wherever we keep it and the zcash node
  4. Someone steals credentials from the zcash node which can be used to retrieve the key from wherever we keep it
    1. Someone steals the key from wherever we keep it.

Thinking about possibilities, trying to start from simplest and work to more complex:

A. Keep the wallet in plaintext on the disk of the zcash node. This makes (1) feasible. (2) is feasible but it doesn't really matter. We don't have to worry about (3) because there is no transit. (4) and (5) are the same as (1). B. Keep the wallet encrypted on the disk of the zcash node and manually decrypt it roughly once per OS boot. This makes (1) hard. (2) is feasible because the wallet will need to be decrypted into memory to actually use it. (3) is not a concern, again, because the key doesn't move. (4) is not much of a possibility since the encryption key would not be kept on the node. (5) is a possibility but using SSH and GPG probably makes it unrealistic. C. Keep the wallet off-site (for example, on hardware under the physical control of Least Authority). Send the wallet to the node for storage in memory roughly once per OS boot. This makes (1) hard. (2) is still feasible. (3) may be possible but is probably of low concern if using SSH or TLS correctly. (4) is not possible because the wallet is pushed to the node, not pulled. (5) may be a concern depending on how the off-site storage is managed. D. Keep the wallet off-site (as above). Provide an API which the node can use to request it. Or, keep the wallet encrypted on the zcash node and provide an API which the node can use to decrypt it / request the decryption key. This makes (1) hard. (2) is still feasible. (3) may be feasible but is probably of low concern if using SSH or TLS correctly. (4) is a concern since the zcash node will need to authenticate itself to prove it should be given the keys. (5) may be a concern depending on how the off-site storage is managed.

From a security standpoint, the best option from among these seems to be (C) which is only inherently vulnerable to (2) - to which all other options are also obviously vulnerable. However, it does come with some operational liability not present in some of the other options. Specifically, services depending on the wallet will be unavailable after an OS reboot and before an administrator re-supplies the keys.

We might initially suppose that the OS is stable and unattended OS reboots will be rare.

This option seems to generalize to other keys. For example, it parallels the ad hoc solution currently in place for managing Onion service keys. These are kept off-site and delivered to volatile storage (ramfs) on the Tor node using nixops send-keys.

exarkun commented 5 years ago

E. Keep the wallet off-site. Push a quantity of unused viewing keys to the node from time to time. Allocate the viewing keys to new accounts as necessary. Push new keys before the old keys run out.

This is better than (C) because it is not even vulnerable to (2). The only thing that can ever be stolen from the zcash node are viewing keys. This event would reveal some transaction history (but still not end-user PII). Meanwhile we can maintain the master and spending keys under our physical control at all times.