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 key
safely with the user? Maybe encrypt the information using keyxyz
and then provide a secure link to the user to click and view thexyz
encryption 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