Contents

A web project needs encryption on three levels: in transit — HTTPS everywhere, including internal connections; at rest — encrypted disks, backups and file storage; and for individual database fields — passport details, tokens and other highly sensitive information. Passwords, meanwhile, are hashed rather than encrypted. The hardest part of encryption is not the algorithms but storing the keys safely.

Here is what to encrypt and where, how encryption differs from hashing and how to manage keys.

How does encryption in transit differ from encryption at rest?

Encryption in transit protects data as it travels over the network: from browser to server, from application to database, from service to service. Encryption at rest protects data on disks, in backups and in storage — in case a disk is stolen, a backup leaks or storage is accessed.

Level What it protects against How it is done
In transit Traffic interception HTTPS/TLS for the site, API, database and internal services
Disks and volumes Stolen or disposed disks Disk encryption by the provider or the OS
Backups Leaked backups Encrypted archives, key kept apart from the copies
Database fields Access via SQL injection or a dump Encrypted in the application before writing
Files Storage leaks Server-side or application-side encryption

Why are passwords hashed rather than encrypted?

Passwords are hashed because they never need decrypting: at sign-in it is enough to compare the hash of the entered password with the stored one. An encrypted password can be decrypted if the key is stolen; a hash cannot. Use slow, salted algorithms, not fast ones like MD5 or SHA-256.

// Sign-up: store only the hash (bcrypt or argon2id)
$user->password = Hash::make($request->password);

// Sign-in: compare the entered password with the hash
if (! Hash::check($request->password, $user->password)) {
    throw ValidationException::withMessages(['email' => 'Invalid credentials']);
}

Slow algorithms such as bcrypt and argon2id make brute-forcing leaked hashes very expensive. Better still, store no passwords at all and move to passkeys — see two-factor authentication and passkeys.

A combination lock on a laptop keyboard Photo: Unsplash

Which database fields should be encrypted?

Encrypt fields whose leak would be especially harmful and that are not needed for search or sorting: passport and national ID numbers, medical information, access tokens for third-party services, users' secret keys. Then even a full database dump is useless without the key.

What to consider:

  1. Search. Encrypted fields cannot be searched — for exact lookups store a separate keyed hash.
  2. Sorting and reports. Encrypted values cannot be sorted or grouped in SQL.
  3. Key outside the database. Keep the key in a secrets manager or environment variables, not next to the data.
  4. Key version. Store a key identifier with the data to make rotation easier.

Better not to store card numbers at all: the payment provider takes them and you keep only a token. See how to accept online payments and fintech product development.

How do you manage encryption keys?

An encryption key is worth more than the data: whoever has the key and database access can read everything. So keys are kept apart from data, given only to the services that need them and rotated regularly.

  • keep keys in a secrets manager or a cloud key management service, never in code;
  • use different keys for different environments and data types;
  • log key usage;
  • rehearse rotation: new key, re-encryption, revocation of the old one;
  • back up keys — without them encrypted backups cannot be restored.

More on storage in secrets management.

What should you check in your project?

A minimal set of checks takes a couple of hours and covers the most common problems. Run it before launch and after major infrastructure changes.

  • HTTPS on every domain with redirects from HTTP and an HSTS header;
  • TLS between the application and the database, cache and queues if they are on different servers;
  • disk and backup encryption enabled;
  • passwords hashed with bcrypt or argon2id;
  • sensitive fields encrypted, with the key stored separately;
  • personal data kept out of logs — see personal data on a website.

In short

  • Encrypt data in transit, at rest and for especially sensitive fields.
  • Passwords are hashed with slow salted algorithms, not encrypted.
  • Field encryption hinders search and sorting — encrypt only what really needs it.
  • Keys live apart from data, with access logs and rehearsed rotation.
  • Do not store card numbers at all — let the payment provider handle them.

FAQ

  • Does encryption slow a site down?

    Barely. Modern CPUs encrypt in hardware, and TLS 1.3 with HTTP/2 even speeds up loading compared with older protocols. Field encryption adds microseconds per write.

  • Can you search encrypted fields?

    Not directly. For exact lookups, store a keyed hash of the value alongside and search by it. Full-text search over encrypted data needs special solutions.

  • What if an encryption key leaks?

    Issue a new key, re-encrypt the data, revoke the old key and then find out how the leak happened. That is why key rotation must be rehearsed in advance rather than improvised during an incident.