Skip to content

poc to showcase client side encryption using hybrid approach.

Notifications You must be signed in to change notification settings

hrishix6/client-side-encryption

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Client Side Encryption

A hybrid approach to encrypt data on client side before sending to backend using both RSA + AES.

Prerequisits

  • Node.js >=22 installed.

Setup

  1. Create a keys folder in the project root.

  2. generate RSA key pair -

openssl genpkey -algorithm RSA -out private.pem -pkeyopt rsa_keygen_bits:2048
openssl rsa -pubout -in private.pem -out public.pem
  1. Put public.pem and private.pem under keys.

Running server

  1. Install dependencies
npm i
  1. Run
npm start
  1. Visit http://localhost:5000

Implementation

On Server

  • Generate RSA Key pair on server, store these keys securely somewhere.
  • Create endpoint to serve RSA public key.
  • On submission of data, extract encrypted AES key, iv and form fields from request.
  • Use private RSA key to decrypt AES key received from client.
  • Use decrypted AES key to decrypt the form data.

On Client

  • fetch RSA public key on initial load from server.
  • When form is submitted, generate a random AES 256-bit key and iv using Web Crypto.
  • Encrypt form fields with this key using AES algorithm of choice.
  • Before submitting data to backend, encrypt AES key itself using RSA public key fetched from server.
  • Send encrypted AES key + form data + iv to backend.

Why would you do this if TLS already provides built-in encryption ?

TLS ensures:

  • Data is encrypted in transit (between browser and server).

  • Data can't be intercepted or modified by attackers while in transit.

  • Server authenticity (via certificate verification).

But TLS does not protect against:

  1. Malicious or compromised frontend

    If an attacker injects malicious JavaScript (via XSS), they can access raw form data before it’s sent via TLS. Rule of thumb is you should never trust client side.

  2. Insider threats on backend

    Developers, DBAs, or insane people might have access to backend DB, logs, or memory — and can see decrypted data. If you are working with extremely sensitive data you should encrypt it at rest.

    If you encrypt sensitive fields at the application level, the backend must explicitly decrypt them, reducing passive exposure.

  3. Data breaches

    Data at rest on server side will be exposed in the breaches if unencrypted, TLS is not even in the picture here.

  4. Zero-trust architecture / secure multi-tenancy

    Sometimes backend services are not fully trusted — app-layer encryption helps in such cases. E.g., encrypting one tenant’s data such that no other tenant or service can decrypt it.

  5. Legal/compliance requirements

    Some industries (finance, healthcare) require field-level encryption, even if data is sent over HTTPS. E.g., HIPAA, PCI-DSS, GDPR recommend/require this for sensitive fields.

Pros and Cons of different approaches

RSA-only Encryption

Encrypts payloads (e.g. form data) directly using RSA public key.

Pros:

  • Simpler architecture: Just RSA keys, no symmetric key handling.

  • No need for hybrid key exchange logic.

  • Public key can safely live on frontend.

Cons:

  • RSA is slow and not designed for large data encryption: Standard RSA (e.g., 2048-bit) can only encrypt up to ~200–245 bytes at a time (depending on padding). You’d need to split large payloads into chunks and reassemble.

  • Bad for performance on mobile / low-power devices.

  • Payload size increases due to RSA padding (especially with longer keys).

  • If you're encrypting more than just a few small fields, it's a bad fit.

When to use this approach:

  • For smaller payloads and low traffic backends RSA is secure and simple.

AES-only Encryption (Never use this for client side encryption)

Encrypt payloads (e.g. form data) using AES key generated on client using web crypto or received from server.

Pros:

  • Faster and more efficient than RSA
  • No need to split large payloads

Cons:

  • Unsafe. If you serve the AES key from server it will be exposed on client side (network tab). If you generate AES key on client side using web crypto, you need to send it to server and it will be exposed on client side (network tab).

When to use this approach:

  • backend-to-backend communication where key is never exposed to untrusted clients.

Hybrid Encryption (RSA+AES)

Generate AES key on client to encrypt payloads (e.g. form data), encrypt AES key using RSA public key received from server.

Pros:

  • Efficient and secure:

    • AES is fast and good for large payloads.

    • RSA is only used to encrypt a small AES key (~32 bytes).

  • Industry standard approach (used in TLS, PGP, etc.).

  • Enables authenticated encryption (AES-GCM gives you integrity checks).

  • Can encrypt whole payloads (not just fields) with ease.

Cons:

  • Complex logic
    • Need to generate and transmit an AES key + IV.
    • Backend must handle AES decryption before applying business logic.
  • Requires secure random generation (usually fine with crypto.getRandomValues()).

Summary

Feature RSA-only AES-only Hybrid (AES + RSA)
Encryption Speed Slow Fast Fast
Large Data Support Bad Good Good
Code Simplicity Simple Simple Complex
Security Secure Unsafe Industry Standard
Frontend Load High Low Low

Rule of thumb

  • Client side cannot be trusted.
  • RSA (asymmetric encryption) is good for small payloads.
  • AES (symmetric encryption) is good for large payloads.
  • Symmetric encryption is only safe is the key is never exposed to untrusted clients.
  • Asymmetric encryption is safe if the private key is never exposed (there's no need either).