In short
Databases get dumped, laptops get stolen, Wi-Fi gets sniffed. Encryption makes sure that whatever leaks is unreadable junk without the key.
Protecting sensitive data both in transit (via HTTPS/TLS) and at rest (encrypting sensitive database fields) so a breach doesn't expose readable sensitive data.

Think of it like this
The padlocked trunk on the train
Sending valuables by train? You lock the steel trunk before it leaves home and only the person with the key opens it at the other end. Even if a porter peeks or the trunk sits in a godown overnight, all anyone sees is a locked box.
Watch it happen
Two places data needs protecting
In transit
- Data moving over a network
- TLS (HTTPS) scrambles every packet
- Stops snooping on Wi-Fi and proxies
At rest
- Data sitting on disk or backups
- Disk or field-level encryption, e.g. AES
- Helps when a disk or dump leaks
You need both. Use HTTPS everywhere, turn on your database's disk encryption, and encrypt extra-sensitive fields like Aadhaar or bank numbers yourself.
The big ideas
What you need to know
The key is everything
Strong encryption with the key stored next to the data is theatre. Keep keys in a secret manager or KMS, away from the database.
Hashing is not encryption
Passwords should be hashed with bcrypt or argon2, which can't be reversed. Encryption is for data you need to read back.
Use authenticated modes
AES-256-GCM both hides data and detects tampering. Never invent your own cipher.
Fresh IV every time
Each encryption needs a new random IV (nonce). Reusing one with GCM can leak your data.
See it in code
Walk through the code
1import { randomBytes, createCipheriv, createDecipheriv } from "node:crypto";2 3const key = Buffer.from(process.env.DATA_KEY!, "hex"); // 32 bytes4 5export function encrypt(text: string) {6 const iv = randomBytes(12);7 const cipher = createCipheriv("aes-256-gcm", key, iv);8 const data = Buffer.concat([cipher.update(text, "utf8"), cipher.final()]);9 return { iv, data, tag: cipher.getAuthTag() };10}11 12export function decrypt({ iv, data, tag }: { iv: Buffer; data: Buffer; tag: Buffer }) {13 const decipher = createDecipheriv("aes-256-gcm", key, iv);14 decipher.setAuthTag(tag);15 return Buffer.concat([decipher.update(data), decipher.final()]).toString("utf8");16}1/4A 256-bit key from an env var, written as 64 hex characters. It never goes in the database.
Store iv, data and tag together (they aren't secret), but never the key. Make one with: node -e "console.log(crypto.randomBytes(32).toString('hex'))".
Save yourself the pain
Common mistakes
Oops
Encrypting passwords so you can 'show them to users later'.
Do this instead
Hash passwords with bcrypt or argon2. Nobody, not even you, should be able to read them back.
Oops
Hardcoding the encryption key in the source file.
Do this instead
Load it from a secret store or env var, and plan how you'd rotate it.
Your mission
Encrypt one sensitive column
Quick check
Which of these should be hashed rather than encrypted?
Go deeper
- 1Confirm all your API traffic is served over HTTPS, never plain HTTP.
- 2Encrypt a genuinely sensitive field, e.g. a national ID number, before storing it.
- 3Learn the difference between encryption (reversible) and hashing (one-way) — use the right one for the right data.
More topics at this stop
Stuck on this topic? Ask an Insider
Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.