Need some clarification regards end-to-end encryption process
Let's say I want to make a messaging(just an example, take it as any data) web(react + node) application(more like an email rather than chat) with end-to-end encryption. So at some point, I will want to send an encrypted(with public key) message and the recipient will need to decrypt it(with private key). Now, say I want to make an encryption process happen on the client(isn't always should be on the client?), so:
user_1want to send a message to
user_1requests public key of
user_1encrypt his message with public key from step 2 and sends it
user_2receive the message and decrypt it with his private key
Now, all sounds great, but...:
- For good UX, a user should know/care only about his own password and all the encryption should magically happen(right?), so generating and storing private key should be done behind the scenes. But how exactly? Storing private key encrypted with user's password, and on the Auth process, send it to the client and then decrypt the private key and store locally for the session. Is that really supposed to be like that?
- Where to store the private key then exactly? Storing in local host isn't really nice due to XSS, storing inside a cookie(secured, samesite etc) also isn't nice due to same XSS and CSRF. Where then?
- Also, it isn't really clear how to secure the connection between the client and the server. Is using SSL(https) really enough? What else can be done?
There are many ways that private key can be stored by the client in a web-based end-to-end encryption application.
One way is not to store the key it at all, but instead, derive the key from a password. The user enters a password, then the private key is derived from the password using a key derivation function, such as PBKDF2.
Another way is to use the Web Crypto API to store the private key in a CryptoKey object, then store the CryptoKey object in the web browser's indexDB storage. See https://crypto.stackexchange.com/questions/35530/where-and-how-to-store-private-keys-in-web-applications-for-private-messaging-wi/52488#52488 for more info on this method.
Another way of storing the private key is the way that ProtonMail does it. The private key is encrypted using another key derived from a password, then the encrypted private key is stored on their server. See https://protonmail.com/support/knowledge-base/how-is-the-private-key-stored/ for more info.
Yet another way of storing a private key is the way that EncryptedSend does it (full disclosure, I am the developer of EncryptedSend). The private key is encrypted using another key derived from a password, then this encrypted blob is written to a file that the user stores on his/her system. To begin a session, the user simply provides this file and the password, then the private key is used both to decrypt messages and authenticate the user with the server.