Currently I am developing a web application that implements a message archiving service. Required is that messages are not readable by the developer / sysadmins, and a nice-to-have would be transmitting the messages end-to-end encrypted. The messages should be readable by all people in a 'business'. Messages that should be archived come in from external sources such as api's or email. These external incoming messages should be considered classified. users should be able to log in from any browser.

In my current test implementation upon creating a 'business' an RSA Keypair will be generated. The public key will be saved in the database associated to the 'business', and the private key will be encrypted using a hash derived from the users password, and stored associated to the user. When other users are added to the business, the decrypted private key of the logged in user will be encrypted using the new users password-derived hash and stored with the new user.

Incoming messages will be encrypted by the business its public key.

When querying messages these will be decrypted by the users private key (the private key will be the same for all users in the business, except they're encrypted with a different password-derived hash). So when a user logs in the password will be used to get the derived hash, decrypt the public key and store it in a server side session. From then messages can be decrypted and served.

The only problem is: by reading the session files, sysadmins are still able to decrypt messages of logged in users. Is there any protocol to solve this?

I have been thinking of client side decryption aswell (by sending the users encrypted private key to the browser, deriving the key from the password in the client side, decrypting the private key using that, and saving the decrypted privatekey temporary in localstorage and decrypt messages from the api using that decrypted private key on the client side, but is storing a decrypted private key in the browser secure?

  • When you say that "Messages that should be archived come in from external sources" does that mean without an active session from the user or without user interaction?
    – ste-fu
    Sep 23, 2017 at 19:36

3 Answers 3


Instead of using your session system to keep track of the key, you may want to try an alternative.

Assign to your user a time-limited, domain-limited and path-limited secure cookie with a newly random "decryption secret" that you generate when checking the credentials of the user in the business group.

If the password is valid, before the login process completes, decrypt the private key with the password and reencrypt it with the "decryption secret". Store the reencrypted private key in the session. Your user is now directed to your webmail page as normal, and the variables used in the login phase are hopefully lost.

Now, whenever the user browses your webmail site, it will constantly send the "decryption secret" as a cookie. That can be used by your server-side script, along with the reencrypted private key, to decrypt any e-mail, if necessary.

Still, like @Vitaly menationed, you are not getting perfect ignorance in the server-side. A rogue system administrator could, if s/he really really wanted to, capture the cookies by installing and directing a user to a specific page. S/he could also capture the HTTP packets, especially if they are not already encrypted with TLS (which would render most of this useless). S/he could also inspect the server's memory. You can also get the password with any of these methods, since you are inside the server.

However, this scheme ensures that the decryption secret will not be stored on the server and does not require any client-side decryption, the same way passwords are typically not stored in your database. It would require the system administrator to make an actual effort in order to read the e-mails, i.e., one could not just stumble upon the private key. And that may be good enough for your threat model.

  • It sounded to me that you were already really close to the solution you wanted, but you were using session management instead of cookies. Well, your session management framework is definitely using cookies too. So if you are careful in how you set your cookies (expire-time, domain, path, and deny access in javascript) it should be fairly easy to come up with a scheme where your server does not need to store the private key, since it is constantly reminded of the details needed to get it on an access-basis. You could store the private key in your cookie, but I would discourage that strongly.
    – Ricardo M.
    Sep 25, 2017 at 17:26
  • Oh let me not forget, be careful with CSRF, because "whenever the user browses your webmail site, it will constantly send the "decryption secret" as a cookie".
    – Ricardo M.
    Oct 1, 2017 at 12:15

The only problem is: by reading the session files, sysadmins are still able to decrypt messages of logged in users. Is there any protocol to solve this?

You are asking for the impossible - for a system that would provide users with decryption and encryption services while not maintaining any knowledge about how it does it, at any time (otherwise sysadmins will be able to decrypt messages, too!).

You have to decide who you trust and to what degree, because you need to trust someone - in the end it's hardware that runs your code, not you yourself.


The biggest risk of storing the key client side is a XSS attack.

The security of your aplication then largely depends on you sucessfully preventing that. This could prove particularly difficult as an attacker presumably has a lot of leeway in crafting a message as emails have a wide variety of permitted characters and encodings.

I do quite a lot of .net development and the number of times I see a question on stackoverflow like "How do I display user supplied html content on my website" with an answer like "Use @Html.Raw()" is unbelievable. Most web frameworks have excellent escaping mechanisms to prevent XSS attacks, yet many developers are unaware of them or of when they actively bypass them.

I'm not saying that you can't correctly display an html format email on a web page without parsing for possible attacks, just that it would be very easy to make a mistake.

On the whole I think storing the key locally would make me pretty nervous given the likely message content and the fact that any attacker only has to email a user to potentially inject code.

Having said that - the decryption key is only useful if you have access to the encrypted content, and a targeted XSS attack against your website could likely read all a user's messages anyway.

You must log in to answer this question.