Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Client-Side Encryption #92

Open
alialbaali opened this issue Aug 1, 2022 · 1 comment
Open

Client-Side Encryption #92

alialbaali opened this issue Aug 1, 2022 · 1 comment
Labels
documentation Improvements or additions to documentation enhancement New feature or request help wanted Extra attention is needed

Comments

@alialbaali
Copy link
Owner

Noto will support cloud hosting as discussed here. It's currently in the work using Supabase for cloud storage, and Bouncy Castle for encryption.

After doing a lot of research and brainstorming, I found out that there are multiple ways it could be implemented. I'll probably go with the following approach:

Upon registration:

  1. User creates an account with email and password.
  2. The password is hashed locally, before transmitting to the server, by using Argon2id algorithm, with a random generated salt in the client.
  3. The password and the salt are sent to the server. Then, the password is rehashed on the server using bcrypt with a work factor of 10, and stored.
  4. Noto generates a password-derived key, called P, by using a KDF (Key derivation function) such as PBKDF2. Store the key locally in a safe, inaccessible location and never transmit it to the server in any circumstances.
  5. For a new folder, generate a symmetric key, called K. Encrypt that folder, its notes, and labels with K. Store the K locally in a safe, inaccessible location, and never transmit it to the server in plaintext.
  6. Encrypt K with P, which results in an encrypted key, called E.
  7. Transmit E to the server, along with the encrypted data.

The process, from 5 to 7, is repeated for each new folder with a different symmetric key K.

Upon login

  1. User enters their email and password.
  2. Get the salt from the server using the user email. Hash the password locally, and send it along with the email address to the server. If password hashes match, the user is logged in.
  3. Noto generates a password-derived key, called P, by using a KDF (Key derivation function) such as PBKDF2. Store the key locally in a safe, inaccessible location and never transmit it to the server in any circumstances.
  4. Get all the encrypted data from the server, along with a different K for each folder.
  5. Decrypt each symmetric key K using password-derived key P.
  6. Decrypt every folder using its own symmetric key K.

This approach is how it's planned to be. I'm still in the early process of the implementation, so things might change. I'll keep updating this issue as I work on the implementation.

Advantages of this approach:

  1. All the data are encrypted and no one would be able to view them except their owner.
  2. Ability to change user password without having to re-encrypt all the data, but only the symmetric keys for folders.
  3. By using a random different salt for each password, we're making sure that two passwords won't produce the same hash.
  4. Not sending the password to the server, meaning the server doesn’t know the user password at all, as the server could be logging or affected in some way.
  5. If an attacker managed to get access to the server database, they won't be able to decrypt the data, as they need the password-derived key P, which is never transmitted and only stored locally on the user device.
  6. If an attacker managed to get access to the server database, they won't be able to obtain the password quickly, as a different salt is being used for each new user. Meaning, it would prevent pre-computed password-hash pairs aka Rainbow Tables. They would need to create a new table for each password.
  7. If an attacker managed to get access to the communication between the server and the client during registration or login, they won't be able to obtain the password which is used to encrypt the data, as the hash is sent. This also helps to prevent the attacker from knowing the password pattern for that user, which has a high possibility of being used in other websites or apps.

Disadvantages of this approach:

  1. If the user forgets their password, they would lose all of their data, since the key that used to encrypt the data is based on the password. However, they might be able to get their account back without any data.
  2. The salt is available publicly for anyone that has the API key. The API key is never shared to anyone nor available in the version control (GitHub). But, it is possible to obtain it by decompiling the APK. So, I might need to find a better way to store it.

If you have any suggestions, please share them!

Resources:
https://security.stackexchange.com/questions/88984/encrypting-with-passwords-encryption-of-key-vs-data
https://security.stackexchange.com/questions/30193/encrypting-user-data-using-password-and-forgot-my-password
https://stackoverflow.com/questions/7529582/how-to-store-private-encrypted-user-data-in-the-database-but-make-them-availabl
https://stackoverflow.com/questions/18057390/how-can-i-encrypt-data-with-a-password-but-allow-said-password-to-be-reset
https://stackoverflow.com/questions/12935409/safely-generated-encryption-key-from-users-password
https://bitwarden.com/help/what-encryption-is-used/#aes-cbc
https://security.stackexchange.com/questions/174647/end-to-end-encryption-with-multiple-users
https://crypto.stackexchange.com/questions/22678/how-secure-is-it-to-use-password-as-aes-key
https://stackoverflow.com/questions/45563332/aes-encryption-example-class-to-encrypt-data-using-users-password
https://stackoverflow.com/questions/1949640/does-iv-work-like-salt
https://cryptobook.nakov.com/
https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html

@alialbaali alialbaali added documentation Improvements or additions to documentation enhancement New feature or request help wanted Extra attention is needed labels Aug 1, 2022
@alialbaali alialbaali pinned this issue Aug 8, 2022
@alialbaali alialbaali unpinned this issue Jun 8, 2023
@alialbaali alialbaali pinned this issue Jun 8, 2023
@opk12
Copy link

opk12 commented Oct 14, 2023

Matrix (mentioned in #91) implements transparent E2EE in the client-side libraries. You get security updates for free and don't have to roll your own crypto (which general crypto wisdom considers a red flag).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

3 participants
@alialbaali @opk12 and others