brave / vault

Brave personal data store vault.
https://brave.com
Mozilla Public License 2.0
19 stars 18 forks source link

transition appState endpoint to store history #36

Closed KevinGrandon closed 8 years ago

KevinGrandon commented 8 years ago

History is probably going to be the thing that we sync across devices, and not necessarily appState.

We'll likely encrypt history items in the browser using a public key, and decrypt them when they come back.

Just sketching some thoughts out as to what we need for the schema:

Possibly also consider adding an encrypted icon URL so we can surface this in the UI if desired.

bridiver commented 8 years ago

I was thinking we might want to merge the intents and history into "events". There could be various kinds of events that we want to track. The basic ones could be something like:

and then more interesting events for things like search phrases, bookmarks, tab/viewport visible/hidden, scroll position, etc..

diracdeltas commented 8 years ago

Is the only goal of encrypting to hide information from the server? If so, symmetric key encryption should be sufficient.

For symmetric key encryption (AES), the initialization vector should never be reused. So either all encrypted fields (title and url) need their own IV or they can be combined into a single field and then encrypted.

bridiver commented 8 years ago

the existing plans for the vault have an asymmetric pair for signing/auth and a symmetric key (encrypted by the public key) for encrypting the actual data. Won't most crypto libraries generate a random IV every time if you don't specify one?

diracdeltas commented 8 years ago

This is a pretty good summary of client-side encryption for sensitive data in popular browsers: http://gregoryszorc.com/blog/category/security/. In short, the most popular option is to stretch a user-provided passphrase into a 256-bit AES key and encrypt/authenticate using that. I am failing to see why we need asymmetric keys here.

The webcrypto API requires you to manually specify the IV.

bridiver commented 8 years ago

the asymmetric keys are primarily used to sign the symmetric encrypted data when it is sent to the vault. We authenticate the message by validating the signature using the public key. I wanted to avoid any kind of session based authentication and it also frees us from having to process the authentication in real-time. We can log the requests at a CDN in real-time and load them in small batches asynchronously

diracdeltas commented 8 years ago

You can authenticate messages using symmetric keys with AES-GCM, which is supported in webcrypto, or by using HMAC. https://en.wikipedia.org/wiki/Galois/Counter_Mode#Encryption_and_authentication

API-wise, calling crypto.subtle.decrypt with AES-GCM should verify the message as well as decrypt it.

bridiver commented 8 years ago

I think there may be a part of the process that isn't clear for the vault. The Vault itself can't and shouldn't be able to read the encrypted data. The keys are generated by the client and the only thing that is shared with the vault in the clear is the public key. The problem with the other methods is that they all required the vault to hold some kind of secret/key which could be compromised. In the asymmetric method we don't have to secure anything because the public key can be stored in the clear. I actually had this exact conversation with @mrose17 and we ended at the same conclusion

mrose17 commented 8 years ago

right. to be clear: the only thing the vault uses is a public key to verify signatures.

the vault also stores encrypted symmetric keys that are deciphered on the browser and then used to decipher encrypted information that is stored on the vault.

since the vault never has access to any plaintext symmetric key, it (or a third-party that has dumped it's database) should never be able to get at any encrypted information.

diracdeltas commented 8 years ago

To be clear, I didn't mean that the vault should store the AES symmetric key. This is essentially only shared between clients via some kind of pairing (like scanning a QR code, or manually entering a passphrase).

It looks like you only have an asym. key pair so that the vault can verify signatures over the synced data, but I'm not sure why the vault needs to do this at all. The clients can verify authenticity of the synced data using the shared secret key when it gets downloaded.

mrose17 commented 8 years ago

basically, the vault uses verification of the signature as a proxy for authorization. if a client knows the private key used to sign payloads for a persona (user), then they are de facto authorized.

diracdeltas commented 8 years ago

Clarified with @bridiver in Slack; I was confused because I thought the public key was used for verifying data integrity, not authorizing accounts.

mrose17 commented 8 years ago

overtaken by events: any user information is recorded by the client in the vault as an opaque encrypted "blob"; accordingly, no action is required!