LibreChat icon indicating copy to clipboard operation
LibreChat copied to clipboard

WIP šŸ”‘feat: Implement End-to-End Encryption `E2EE` Across Messaging

Open rubentalstra opened this issue 9 months ago • 5 comments

Summary

This PR introduces a comprehensive end-to-end encryption (E2EE) feature that secures both message content and user credentials using modern cryptographic standards. The changes span across backend models, API endpoints, controllers, and client-side components to ensure that sensitive data is encrypted during transit and at rest.

Closes: #5712 Closes: #5975 reference: #5856

Key highlights include:

  • Message Encryption:

    • AES-GCM Encryption: All outgoing messages are now encrypted using AES-GCM. When a user with an active encryption configuration sends or receives a message, the plaintext is converted to ciphertext using a randomly generated 256-bit AES key and a 12-byte initialization vector (IV).
    • RSA Key Wrapping: The AES key is encrypted with the recipient’s RSA public key (provided in PEM format) using RSA-OAEP with SHA-256. This ensures that only the intended recipient, who possesses the corresponding private key, can decrypt the AES key and then the message content.
    • Data Model Updates: The Message model and its schema have been updated to include additional fields such as iv, authTag, and encryptedKey for storing encryption metadata. These changes propagate through all related methods (e.g., saving, updating, and retrieving messages) to handle encryption parameters properly.
  • User Encryption Settings:

    • Encryption Setup UI: A new UI component, EncryptionPassphrase, has been added to the settings tab. Users can set or change their encryption passphrase. The passphrase is used to derive a symmetric AES-GCM key (via PBKDF2) to encrypt the user’s RSA private key.
    • Key Pair Generation: Upon activation, a new RSA-OAEP key pair is generated. The public key is stored in the user’s profile, while the private key is encrypted using the derived key, with both encryption salt and IV stored as part of the user’s settings.
    • Disabling Encryption: Users also have the option to disable encryption. In this case, all encryption-related fields are set to null, ensuring that no cryptographic operations occur when handling messages or other sensitive data.
  • Controller Enhancements:

    • AskController Enhancements: The response generation logic in AskController now includes an encryption branch. If the user has a valid encryption public key, the plaintext response is encrypted before being sent to the client. This ensures that even automated or AI-generated messages are secured.
    • UserController Updates: Additional endpoints have been added for updating user encryption settings, enabling clients to change their encryption keys or disable encryption entirely.
  • Client-Side Decryption:

    • MessageContent Updates: On the client side, message components (e.g., MessageContent.tsx) have been updated to include decryption logic. If a message is received with encryption metadata (i.e., iv, authTag, and encryptedKey), the client uses the stored RSA private key (after decryption with the user’s passphrase) to decrypt the AES key, which in turn decrypts the message.
    • Error Handling: Enhanced error logging and error UI components are in place to handle decryption failures gracefully, providing users with clear notifications if any issues occur during the decryption process.
  • API & Data Provider Adjustments:

    • New Endpoints: An API endpoint (/api/user/encryption) has been added to handle updates to user encryption settings.
    • Mutation Hooks: New hooks and mutations (e.g., useSetUserEncryptionMutation) have been implemented to seamlessly update user encryption keys from the client.
    • Schema Updates: Data schemas have been revised to ensure that encryption fields are treated as nullable strings, which is vital for proper type handling and backward compatibility.

Change Type

  • [x] New feature (non-breaking change which adds functionality)
  • [x] This change requires a documentation update

Testing

To test the E2EE functionality, please follow these steps:

Test Configuration:

  1. Frontend Testing:
    • Encryption Activation:
      • Navigate to the chat settings and activate encryption by entering a valid passphrase. Verify that a new RSA key pair is generated and that the public key is displayed (truncated for brevity) in the UI.
    • Message Encryption/Decryption:
      • Send a message from an account with encryption enabled. On the receiving side, check that the message content is decrypted correctly.
      • Temporarily disable encryption and verify that messages are transmitted and rendered in plaintext.
    • Error Scenarios:
      • Test with an incorrect passphrase to simulate decryption failure. Ensure that a clear error message is displayed and logged.
    • UI Regression: Validate that non-encryption related functionalities (e.g., file attachments, UI layout) continue to operate as expected.

Checklist

  • [x] My code adheres to this project's style guidelines
  • [ ] I have performed a self-review of my own code
  • [x] I have commented in any complex areas of my code (especially in the encryption and decryption logic)
  • [x] I have made pertinent documentation changes (see inline comments and updated README/technical docs)
  • [x] My changes do not introduce new warnings
  • [x] I have written tests demonstrating that my changes are effective or that my feature works
  • [ ] Local unit tests pass with my changes
  • [x] Any changes dependent on mine have been merged and published in downstream modules.
  • [ ] A pull request for updating the documentation has been submitted.

rubentalstra avatar Feb 16 '25 08:02 rubentalstra

Screenshot 2025-02-16 at 10 43 45

rubentalstra avatar Feb 16 '25 09:02 rubentalstra

@danny-avila need some help here šŸ˜… to decrypt the refresh callback? where can I find this because it's a little maze with the chat's and messages and conversations

https://github.com/user-attachments/assets/616be36c-7cca-4b97-8c09-36b25073f720

Screenshot 2025-02-16 at 10 43 45

rubentalstra avatar Feb 16 '25 16:02 rubentalstra

the hook useGetMessagesByConvoId is what makes the api/messages request, that would be the easiest place to start. it should be done within the hook.

() => dataService.getMessagesByConvoId(id),

what this function returns is what ends up getting cached in the query cache, so it would be best to do it here, i think.

to use atom store, you would need to move useGetMessagesByConvoId from packages/data-provider to client/src/data-provider/Messages/queries.ts (doesn't exist yet)

https://tanstack.com/query/v4/docs/framework/react/reference/useQuery

Reference ā„¹ļø ^

rubentalstra avatar Feb 17 '25 22:02 rubentalstra

Hi @danny-avila and @rubentalstra! Firstly I wanted to say this project is awesome and really the best open source LLM chat around! I'm taking it to the company I work on and the feature addressed here was a main concern of mine. I got very happy to see it was already under development, but I noticed that this PR is not mentioned on the project roadmap. Is it planned to be integrated in next releases?

marcelomendoncasoares avatar Apr 10 '25 18:04 marcelomendoncasoares

+1

Hi @danny-avila and @rubentalstra! Firstly I wanted to say this project is awesome and really the best open source LLM chat around! I'm taking it to the company I work on and the feature addressed here was a main concern of mine. I got very happy to see it was already under development, but I noticed that this PR is not mentioned on the project roadmap. Is it planned to be integrated in next releases?

KiGamji avatar Apr 22 '25 22:04 KiGamji

@rubentalstra, is the work still ongoing?

tfactor2 avatar Jul 02 '25 16:07 tfactor2

@rubentalstra, is the work still ongoing?

No not this PR. Sorry about that.

rubentalstra avatar Jul 02 '25 16:07 rubentalstra

@rubentalstra, is the work still ongoing?

No not this PR. Sorry about that.

@rubentalstra Any other PR or plans aiming for E2E encryption of user chats?

agp89 avatar Jul 02 '25 17:07 agp89

@rubentalstra this is exactly what I'm looking for! Did you discontinue work for lack of time, or was it because there were deeper issues that made it seem infeasible? I'm wondering if I can finish this up and get it to a stage where it's ready for review. Thank you for getting this ball rolling.

borenstein avatar Oct 28 '25 12:10 borenstein

@rubentalstra this is exactly what I'm looking for! Did you discontinue work for lack of time, or was it because there were deeper issues that made it seem infeasible? I'm wondering if I can finish this up and get it to a stage where it's ready for review. Thank you for getting this ball rolling.

@borenstein the main issue from my side was a lack of time. I'm sorry about that.

rubentalstra avatar Oct 28 '25 12:10 rubentalstra

so I assume bedrock PRs will also be closed? huh?

KiGamji avatar Oct 28 '25 12:10 KiGamji

@rubentalstra Nothing to apologize for! I'm thinking of picking it up. Do you recall where you left things?

borenstein avatar Oct 28 '25 14:10 borenstein

@rubentalstra Nothing to apologize for! I'm thinking of picking it up. Do you recall where you left things?

@borenstein I think starting from scratch is the best thing to do. Because one of the roadblocks was also the problem that the whole frontend mechanism would be rewritten during my development of this feature.

The struggle I encountered:

  • Streaming data from api to server to save it was encrypted but then the frontend did a full refresh of the response and it lost its encryption.

I hoop this clears some stuff up?

rubentalstra avatar Oct 28 '25 14:10 rubentalstra

Indeed it does, and thank you for your quick responses! @danny-avila is the front-end stable enough now for a new try at E2EE?

borenstein avatar Oct 28 '25 14:10 borenstein

I’m also interested in this feature. In an ideal scenario, users would feel more comfortable using the app if none of the admins could read their messages. @borenstein, I’d appreciate it if you could add me to any PRs you’re working on or find a way to keep us updated on the progress.

kmilo9999 avatar Nov 04 '25 14:11 kmilo9999