Client Side Encryption - Detailed

In order to encrypt your message, your browser uses a couple of open source libraries: forge.js, crypto.js and openPGP.js
All of these libraries are open sourced and well audited.

Right after you write an email and click the send button, your browser makes a special request to the server to retrieve public keys for the recipient. When the server finds the existing recipient, it returns the data that contains the public key for the person you are wanting to send an email to.

Notice that the recipient email is never sent in clear text, but an SHA512 hash is used, so the server is unaware of the real recipient's email address.

After your browser successfully retrieves the public key, a script running on your computer generates a random 256 bit AES key that is used to encrypt your email message, and files (if you include attachments). The AES key is encrypted with the recipient's public key. After these operations are done, we send the information to the server, which stores that information for the recipient. Encrypting the AES key with the recipient public key guarantees that only the person who holds the corresponding private key will be able to decode it. This is also what is called the PGP standard. The benefit of this technique is the protection of user information not only from an attacker but from a server as well.

Unfortunately, there are attacks that PGP cannot address:

If a server provides a fake public key to the sender and the server has the corresponding private key, it can decode it and re-encrypt with the genuine recipient public key.

It's arguable that if you don't trust the service you are using, there is a chance that it can ship you JavaScript code containing backdoor access in the first place. However, keep in mind that in this scenario, a user can still audit code personally or use offline stored files.

At SCRYPTmail, we were able to come up with a solution where you can use the hash of a public key as an email address. It will look very similar to a bitcoin wallet address. As a result, when your browser requests a public key, it will be able to compare the hash of the public key with the information provided by the sender to validate if it's a match. This process ensures the sender that keys returned by the server are genuine.