TechTrailCamp Architecture Consulting
← Back to Blog

Client-Side vs Server-Side Encryption: Differences & Approaches

WHERE DOES THE DATA GET ENCRYPTED? Client-Side Client encrypts here 🔒 ciphertext travels Server / Cloud stores blob, can't read Server never sees plaintext Server-Side Client sends plaintext (over TLS) Server / Cloud encrypts here 🔒 Provider manages keys The question is simply: who holds the keys, and where does plaintext exist?

"Is the data encrypted?" is the wrong question. Any serious system encrypts data both in transit (over the network, via TLS) and at rest (on disk). The question that actually trips people up is about encryption at rest: who performs the encryption, and who holds the keys? That single distinction is what separates client-side encryption from server-side encryption — and it has real consequences for security, compliance, and operational complexity.

First, a Quick Foundation

Three terms get muddled constantly. Let's separate them:

  • Encryption in transit — protecting data as it moves across the network (HTTPS/TLS). This is orthogonal to today's topic; you should always do it regardless.
  • Encryption at rest — protecting data while it sits stored on disk. This is what client-side vs server-side is about.
  • Key management — generating, storing, rotating, and controlling access to the encryption keys. This is the real heart of the matter; encryption is easy, key management is hard.
The cipher (AES-256, etc.) is rarely the interesting decision. The interesting decision is where the plaintext exists and who can access the keys. Client-side and server-side encryption answer those two questions differently.

Server-Side Encryption (SSE)

With server-side encryption, the client sends plaintext to the server (protected in transit by TLS), and the server encrypts it before writing it to disk. On read, the server decrypts it and returns plaintext. The encryption and the keys live on the server/provider side.

The flow:

  1. Client sends plaintext over TLS.
  2. Server receives plaintext (it can see your data at this moment).
  3. Server encrypts with a key it manages and stores the ciphertext on disk.
  4. On read, the server decrypts and returns plaintext to the client.

The defining property: the server sees your plaintext and controls the keys. This protects you against one specific threat — someone who steals the physical disks or accesses raw storage gets only ciphertext. It does not protect you against a compromised or malicious server, because the server can decrypt at will.

Strengths:

  • Trivially easy — often a single flag or default. No crypto code in your application.
  • No client-side key management burden; the provider handles rotation and storage.
  • Negligible performance impact; the provider does it at the storage layer.
  • Satisfies most "encryption at rest" compliance checkboxes.

Weaknesses:

  • The provider (and anyone who compromises it, or is legally compelled) can access your plaintext.
  • Protects mainly against stolen-disk / raw-storage-access threats, not against a breached application or provider.

Client-Side Encryption (CSE)

With client-side encryption, the data is encrypted on the client before it ever leaves. The server only ever receives — and only ever stores — ciphertext. It cannot read your data because it never has the plaintext or, ideally, the keys. The client encrypts on the way out and decrypts on the way back in.

The flow:

  1. Client encrypts plaintext locally using a key it controls.
  2. Client sends ciphertext over TLS.
  3. Server stores the ciphertext — it is an opaque blob to the server.
  4. On read, the client receives ciphertext and decrypts locally.

The defining property: the server never sees plaintext. This is the foundation of "zero-knowledge" / end-to-end encrypted products (password managers, Signal, end-to-end encrypted backups). Even if the storage provider is fully breached, the attacker gets only useless ciphertext.

Strengths:

  • Strongest confidentiality — the provider, a rogue admin, or a full server breach cannot read your data.
  • You retain full control of keys; protects against an untrusted storage layer.
  • Meets the strictest compliance and data-sovereignty requirements.

Weaknesses:

  • You own key management — and that's genuinely hard. Lose the key and the data is gone forever; no provider can recover it.
  • The server can't operate on the data — no server-side search, indexing, or processing of plaintext (you only get to work with opaque blobs).
  • More application complexity and some client-side performance cost.
Who Sees Plaintext? Who Holds the Keys? Question Server-Side Client-Side Where encryption happens On the server On the client Server sees plaintext? Yes No Who holds the keys Provider (usually) You / client Protects against breached server? No Yes Server-side search / processing Yes No Lost-key data recovery Possible Impossible Operational effort Low High
The trade-off in one view: security control vs convenience and functionality

The Glue: Envelope Encryption & Key Management

Both models rely on good key management, and the dominant pattern in both is envelope encryption. Instead of encrypting data directly with one master key, you use two layers:

  1. A Data Encryption Key (DEK) — a fresh symmetric key (e.g. AES-256) that actually encrypts the data. A new one is typically generated per object/file.
  2. A Key Encryption Key (KEK) / master key — held in a secure key vault (like AWS KMS), used only to encrypt the DEK, never the data itself.

You then store the encrypted DEK right alongside the ciphertext. To decrypt, you ask the key vault to unwrap the DEK, then use the DEK locally. This is powerful because the small master key never leaves the vault, rotating the master key doesn't require re-encrypting terabytes of data, and access to data can be controlled simply by controlling who can call "unwrap the DEK."

Envelope Encryption Your Data encrypted with the DEK DEK Data Encryption Key wrapped by the KEK KEK / Master Key stays inside the key vault (KMS / HSM) never leaves; only unwraps the DEK Store the encrypted DEK next to the ciphertext · rotate the KEK without re-encrypting data
Envelope encryption: a per-object DEK does the work, a vaulted master key protects the DEK

Approaches in Practice: The AWS S3 Example

AWS S3 is the clearest place to see every variation side by side, because it offers all of them. The differences come down entirely to where encryption happens and who controls the key.

Server-Side options (AWS encrypts on its side)

  • SSE-S3 — AWS generates, manages, and rotates the keys entirely. Simplest; the default for S3. You do nothing but turn it on.
  • SSE-KMS — AWS still encrypts server-side, but the master key lives in AWS KMS, giving you audit logs (every decrypt is logged in CloudTrail), fine-grained IAM access policies, and controlled rotation. The most common enterprise default.
  • SSE-C — AWS does the encryption, but you supply the key with every request. AWS uses it and immediately discards it, storing only an HMAC to verify future requests. You manage the key; AWS does the crypto.

Turning on SSE-KMS is essentially one parameter on the upload:

# Server-side encryption with a KMS-managed key
aws s3 cp report.pdf s3://my-bucket/report.pdf \
    --sse aws:kms \
    --sse-kms-key-id alias/my-app-key

# AWS receives plaintext, encrypts it server-side using the KMS key,
# and logs the key usage in CloudTrail.

Client-Side option (you encrypt before sending)

With the AWS Encryption SDK (or the S3 Encryption Client), your application encrypts the object locally — typically using envelope encryption with a KMS or local master key — and uploads only ciphertext. AWS S3 stores an opaque blob it cannot read. Conceptually:

# Client-side: encrypt locally, THEN upload the ciphertext
plaintext      = read_file("report.pdf")
data_key       = kms.generate_data_key(KeyId="alias/my-app-key")   # returns plaintext DEK + encrypted DEK
ciphertext     = aes_encrypt(plaintext, data_key.plaintext)
discard(data_key.plaintext)                                        # never persist the plaintext DEK

# Upload ciphertext + the *encrypted* DEK as metadata
s3.put_object(Bucket="my-bucket", Key="report.pdf",
              Body=ciphertext,
              Metadata={"x-enc-key": data_key.encrypted})

# S3 only ever holds ciphertext; decryption requires calling KMS,
# which your IAM policy controls and CloudTrail audits.

The mirror image exists across the stack: databases offer Transparent Data Encryption (TDE) as a server-side approach, while application-level / field-level encryption (encrypting a column like a national ID before it touches the database) is the client-side approach. Azure (Storage Service Encryption vs client-side SDK) and GCP (Google-managed, CMEK, and CSEK keys) follow the exact same pattern.

Which Should You Use?

  1. Default / most workloadsSSE-KMS (or your cloud's equivalent). It checks the compliance box, gives you audit logging and access control, and costs almost no effort. Good enough for the vast majority of systems.
  2. Highly sensitive data where you cannot trust the provider with plaintext (health records, secrets, regulated PII, zero-knowledge products) → client-side encryption. Accept the operational burden and the loss of server-side processing in exchange for the strongest confidentiality.
  3. You must own the keys but want the cloud to do the cryptoSSE-C or customer-managed keys (BYOK / CMEK).
  4. Anything in transit → always TLS, independent of the above choice.
Rule of thumb: server-side encryption defends against stolen storage; client-side encryption defends against a compromised or untrusted server. Pick based on which threat you actually need to defend against — and remember the cost of client-side is that a lost key means lost data, permanently.

Common Misconceptions

  • "Server-side encryption protects against hackers." Mostly no — if an attacker breaches the running application or provider, they can decrypt just like a legitimate request. It protects against someone stealing the physical disks or raw storage.
  • "Client-side encryption makes TLS unnecessary." No. They protect different things (data-at-rest confidentiality vs in-transit integrity/confidentiality). Keep using both.
  • "They're mutually exclusive." No — you can layer them. Client-side encrypt the most sensitive fields and enable server-side encryption on the whole store for defense in depth.
  • "Encryption is the hard part." The cipher is the easy part. Key management — storage, rotation, access control, and recovery — is where systems succeed or fail.

Conclusion

The difference between client-side and server-side encryption isn't about the algorithm — it's about where your plaintext exists and who controls the keys. Server-side encryption is easy, lets the provider operate on your data, and defends against stolen storage; it's the right default for most systems. Client-side encryption gives you maximum confidentiality against an untrusted server at the cost of real key-management responsibility and lost server-side functionality. Envelope encryption and a solid key-management service (like AWS KMS) are the connective tissue that makes either approach practical and auditable. Choose deliberately, based on the threat you're actually defending against.

At TechTrailCamp, encryption strategy and secure system design are exactly the kind of decisions our architecture consulting helps teams get right — grounded in real production systems.

Want to design secure, compliant systems with confidence?

Get architect-led guidance to design and scale encryption, key management, and cloud security in production.

Book a Discovery Call