In my previous article, I've presented the Seshat project. One of the feature I want to implement is the client side encryption in order to enforce security on contents. However, my main concern now is to define how encryption keys will be handled. I've tried several approaches described after. The encryption mechanism itself and choosing between field encryption level and full object encryption is described in this Github issue.

1. Using account password

The first approach is to use the account password to encrypt and decrypt data.
Pros

  • Easy to implement
  • User will only have to remember one password
  • Password is stored inside the application encrypted in SHA-256 so application won't be able to decrypt data on its own
  • Easy multi devices support

Cons

  • If account password is lost, all content are lost at once
  • In case of password update at the account level, a mechanism to decrypt / re-encrypt all datas for the user has to be done which may take some time depending of amount of data
  • Unable to use OAuth login mechanisms as password is required. For account using such login method, a master password could be asked at first login
  • Password will have to be stored in plain text on the client side which is a security risk as users generally uses the same password for all of their services. Password could be cyphered using an internal key and the cyphered version is used as the encryption key which would avoid plain text password storage.

2. Using a password per novel

Another approach would be to have one user defined password per novel.
Pros

  • Easy to implement
  • Easy multi devices support
  • No storage of the encryption keys on the server in any format
  • If a password is lost, it'll only affect one novel

Cons

  • Bad UX: after user logged-in, he'll be asked to provide another password to access to each content
  • Multiple passwords to be remembered by users which will lead users to choose the same accross all of their projects
  • Like in previous approach, passwords will have to be stored in plain text on the client side with the same security risk for user password to be exposed

3. Keys storage

This final approach mixes the first two ones. At first, a vault to store encryption keys is created for each user. This vault is stored on the server side, encrypted using user password. When user creates a new novel, an encryption key is automatically generated and added to the vault and is used to encrypt / decrypt data on client-side for the novel. User password is required again to encrypt vault before being pushed to server. On client side, only generated keys are available in plain text, user password is kept in SHA-256 just to confirm it is valid when requested (for offline support).
Pros

  • Easy multi devices support
  • No storage of the user password on the client side
  • When user changes password, only vault has to be re-encrypted instead of all content
  • Available plain text keys are not user defined and so not usable on other services to login

Cons

  • If account password is lost, all content are lost at once
  • Still hard to implement using OAuth logins as password is only known by authentication actor, a master key will have to be defined by the user and to be provided after login

Other approaches

I've also tried other approaches like two factor authentication or generated encryption keys on the fly but they also have major issues. Two factor authentication improves security but the secret has to be shared with the server and, when using a mobile, user will have to switch between Seshat application and the authenticator. For generated keys, the issue is that they'll need to be stored on the server in order to support multi devices or the server will need a master key which will totally break the security.

Conclusion

For now, the best option I've found is the third one with a vault of keys stored encrypted using the user password (or a master key for the ones using OAuth login). For me, it is the most balanced between risk and advantages of all the approaches I could think about but if you have other flows in mind, do not hesitate to comment this article.