I have read bunch of answers and tutorials on how client side cryptography is not a good idea because of many reasons listed mainly in Javascript Cryptography Considered Harmful article. Some facts
- The app will be using HTTPS
- There will be server and client side validation
- There is no link between user's password and the following scenario
- The server side is a RESTful web services (no session whatsoever)
- The backend issues JWT to users
- The backend might allow both user/password as well as oauth (i.e. fb, twitter, etc.)
What do I want to encrypt in client side?
The user will be inputing some personal information (i.e. name, address, phone number) via a frontend app (i.e. Vue.js, Angular, React, etc.)
How do I imagine this is going to work?
The user selects fields (i.e. personal information bits and pieces), and then clicks encrypt. The user will provide an encryption key. The frontend will use some js crypto library and encrypt the information and replace them in the DOM and inform the user to backup the encryption key.
How do I communicate this information to server?
The frontend will make a HTTP PUT or POST request with the personal information (whether plain/text or gibberish) to the server. The server don't care about incoming data (i.e. except for sql or other forms of injections) and store it in the database right away. This request will not contain the encryption key but, might contain a flag/s to specify that which fields were encrypted.
How to decrypt?
When the user requests for the information, the backend returns whatever there is in the server as is. The information if encrypted will be displayed as gibberish to the user. Using flags, the system will give them decrypt option and clicking that would ask them to input encryption key and does the decryption locally.
Ultimate purpose?
First of all, every effort will be taken to make sure that server and database and everything is bullet-proof but, if for some reason the server is hacked then the hacker would end up with loads of information that is tied to gibberish personal information.
The ultimate question
Reading through internet, cryptography in Javascript is strongly discouraged hence, my questions
- Taking into account the scenario and requirement above, what are the risks imposing the above implementation?
- Is there an approach that you recommend, where only the user is in control of the key, not stored anywhere?
- If I were to encrypt this information in the backend, how can I communicate the
encrypt keysafely with the user? Maybe encrypt the information using keyxyzand then provide a secure link to the user to click and view thexyzencryption key, ... ? - What other suggestions are there for front-end, backend-based encryption?
I would like to give the user's the confidence that only they know how to decrypt the key. How can I achieve that in a more efficient way? Without having to store and manage the encryption key?
Update July 17, 2018
Based on the accepted answer, I wrote a medium post on how I implemented the solution here is the link https://medium.com/@rhamedy/encryption-decryption-of-data-based-on-users-password-using-pbkdf2-aes-algorithms-592f8c1bb79a