How does "zero access encryption" of Protonmail work?

I’m using proton mail web email, which is described as “zero access” since they (the proton admin) don’t have the key which is supposedly stored on the client side, so they can’t decrypt anything.

But there’s no client side on the web email – I’m just connecting to their servers and logging in. So it seems that they do have all the required info to decrypt, given only my username and password. There’s nothing stored on my computer that decrypts locally as far as I know. If there was such unique key on my local machine then how does it decrypt my emails on any other new machine/phone?

Does anybody know how does it work and if I’m correct here?

Thanks

From Wikipedia : https://en.wikipedia.org/wiki/ProtonMail

…The decryption takes place client-side either in a web browser or in one of the apps. The public key and the encrypted private key are both stored on ProtonMail servers. Thus ProtonMail stores decryption keys only in their encrypted form so ProtonMail developers are unable to retrieve user emails or reset user mailbox passwords.

I believe this article was written when ProtonMail was still using 2 different passwords for login and email decryption. Nowadays there is only 1 password which does both so I’m pretty sure the general explanation about how it works stays the same.

The client in this scenario is your web browser that loads the client code (e.g., in the form of JavaScript). You do not directly connect to the mail server software.

Client side encryption? like tutanota and yes there is nothing called “zero access” you literally using someone’s PC and if he decided to be evil he can be within seconds and send that JS script to steal your keys (again another proof that encryption happens in your browser) and read your emails but to reply on your question :joy: yes the encryption on your side, they know nothing about it

there is still the 2 passwords option (at least when i activated it) but it’s disabled by default

One possibility is:
They store your private OpenPGP key and the corresponding public key on their servers.
Your private OpenPGP key is encrypted using your password. For incoming e-mails, they can use your OpenPGP public key to encrypt them. For everything else, the web client retrieves the encrypted OpenPGP key from their servers when logging in, and you locally decrypt the private key in your web browser. Then, your e-mails can be decrypted by the web client.

1 Like

Having zero-access encryption in webmail is possible as shown above, but there are some problems:
The user must trust the webmail provider and their web interface every time he/she uses the service, and trust that snooping features were not added to the interface.
And, if the password is weak, cracking the encrypted private key may be possible.

That is where 3rd party audits come in.

The files can only be decrypted using the user’s private encryption key. Because the server does not have access to the user’s private encryption key, once the files are encrypted with the user’s public encryption key they are no longer accessible to the server or the server’s owner. When the data owner wants to view their data, they request the encrypted files from the server and decrypt them locally on their device, not on the server.
https://protonmail.com/blog/zero-access-encryption/

In ProtonMail’s one-password mode, the mailbox password is derived from the login password via a one-way cryptographic password hash. The input to this hash includes a salt provided by the server on login but not stored in the client. In this way, compromise of the mailbox password does not automatically lead to compromise of the login password.
In this scheme, however, the login password cannot be sent to ProtonMail directly, as it can be used to calculate the mailbox password and thus decrypt mail. To solve this problem, we have re-engineered our entire login process to never send the login password to our server, which has the added benefit of helping protect against MITM (man-in-the-middle) attacks.
https://protonmail.com/blog/encrypted_email_authentication/

So, to sum it up, ProtonMail doesn’t have your private key. The key to decrypt your emails is calculated locally, since it’s derived from your password (which is never sent to their servers) and the salt provided by the server. If you want to know more about it, you can refer to ProtonMail’s website.

I doubt this. You can’t derive a 4096-bit RSA private key from a user-provided password. If you do this, then the private key would be cryptographically weak.

The purpose of a per-user salt value is rendering the usage of pre-calculated rainbow tables to “dehash” user passwords ineffective. Nowadays, salting passwords should be done by every service that stores passwords. So this doesn’t exist to protect or derive keys.

Moreover, see ProtonMail’s statement on Reddit:

We generate the private key in the browser. Then it is encrypted with AES 256 before it is sent to our server. Since it is encrypted with your mailbox password which never gets set to the server, we are unable to decrypt your private key. When you log in on a different device, the encrypted private key is sent to that device and then your mailbox password decrypts the private key.

Besides, there is an option to export your private key in the settings (see official guidance).

As I understand it, neither the salt to derive the encryption key nor the initialization vector used for encryption need to be kept a secret and can be stored in the server. If these are send over along with the (encrypted) private key the client can then provide the password, derive the decryption key, and decrypt the private key. Is that correct? So the only requirement is that the password is never shared with the server.

Just for clarification and future reference:

Salt in cryptography

A salt is a random per-user value that is used as an additional input for a hash function when storing passwords. The insecure way to store passwords is storing them in cleartext. The more secure way is to store them as a hash value. A hash function takes an input of an arbitrary size and “translates” this into an output of a fixed size. There is no practical way to reverse the process. However, an attacker can pre-compute hashes by just hashing random input.

Simplified example without salt

If you just hash passwords, you get a list like this:

user (original password) password in the database
A examplePassword123 ef63ac7757801244
B AnotherPass987 63faff4cccaef8ca9
C 12345password 40b1b887502902a8
D examplePassword123 ef63ac7757801244
E paspas627 c57b9f9dd8be2343

Maybe, you already see a problem: If two users (here: A and D) use the same password, hashing the password results in the same hash. If they use a common password that is already part of publicly-known password lists (e.g., "password123), then the attacker can easily “de-hash” the password by pre-computing the hashes.

Simplified example with salt

Now, we add a random per-user value and hash both:

user (original password) salt salted password in the database
A examplePassword123 ek9o48lf5b30ufr5sjnr 6256f5986205f86c
B AnotherPass987 asrrzoldgp5fn3y82rp7 7f97ffdfdf36cde11
C 12345password pcdhvo0le9iph560ue97 0328d025248b1477
D examplePassword123 5k6lsgcazse5ljp79r2p 5e11d9382a31c2b8
E paspas627 9vjfbxj6qj5oaqd6zbf5 944442d5e6dc1056

In this scenario, for the attacker it isn’t sufficient to hash a long list of common passwords to “de-hash” the hashes. The attacker must hash the list + the salt PER USER. So the attack becomes much more inefficient. In reality, there are special password hashing algorithms like Argon2 that additionally slow down the hashing process to make such brute-force attempts extremely inefficient.

The log-in process

Without a salt, the “typical” service hashes your password and compares the hash with the one in its database. If the hashes match, you are logged in.

With a salt, the “typical” service takes the salt and the password, hashes both, and compares the result as before.

PS: There is also a similar concept, called “pepper.” Pepper is a secret that is also used as an input for the hash function, but it is generated per application, not per user.

Initialization vector

The IV adds pseudo-randomness to certain cryptographic operations. The pseudo-randomness ensures that encrypting identical parts of a message doesn’t result in the same ciphertext. However, if you reuse the same IV all the time, encrypting identical parts again results in the same ciphertext. Therefore, it is crucial to never reuse IVs.

1 Like

Yes, a simplified example is:

During registration, I generate a salt value for you and you send your new password. I take both, hash them, and store the result in my database. Additionally, I generate a OpenPGP key pair in your web browser and encrypt the private key with your password. Then, I store the unencrypted public key and the encrypted private key in my database.

If you get a new e-mail, I can take your public key to encrypt the e-mail. The properties of asymmetric crypto ensure that I can’t decrypt the e-mail afterward without having the corresponding private key.

If you log in, you send me your password. I take the stored salt value and your password, hash both, and compare the resulting hash with the one in the database. If they match, I allow access to your mailbox with the encrypted e-mails and send the encrypted private key to your web browser. You web browser decrypts your private key and uses the decrypted private key to decrypt your e-mails.

In the case of Protonmail, they seem to make certain actions more secure than explained above. However, there are some problems:

  1. If Protonmail copies the unencrypted e-mails before encrypting them with your public key, the original e-mails remain accessible.
  2. If Protonmail stores an unencrypted copy of your private key, they can decrypt your e-mails.
  3. If Protonmail uses a weak mechanism to generate the key pairs, the keys may be cryptographically weak (for instance, see the ROCA vulnerability).
  4. If Protonmail gets your password, they can decrypt your private key and decrypt all e-mails.

Plus, there are issues with OpenPGP in general that need to be considered.

To increase security (but this also increases complexity and decreases usability), you could use another OpenPGP key pair on top of this and store the private key locally.

1 Like

Excellent example, much clearer now thank you. It seems there are too many moving parts and the issue once again becomes one of trust on the provider, rather than the algorithms involved. Although with email, many are already unencrypted due to how the world has evolved and this seems unlikely to change. In that regard, modern messengers like Signal are probably a much better option since you are always the one and only in control of all your keys.