security

Describe the difference between symmetric and asymmetric encryption, and when each is appropriate.

Think of symmetric encryption like a shared house key. Everyone who needs access gets a copy of the same key. Fast, simple, but if one copy gets stolen, t...

15 Mar 2024

Think of symmetric encryption like a shared house key. Everyone who needs access gets a copy of the same key. Fast, simple, but if one copy gets stolen, the whole house is compromised.

Asymmetric encryption is more like a mailbox. Anyone can drop a letter in (public key), but only the owner can open it (private key). Slower, but you never need to hand out the key that unlocks things.

Symmetric encryption

One key encrypts. The same key decrypts. That is the whole model.

Js
const crypto = require('crypto');

const key = crypto.randomBytes(32);
const iv = crypto.randomBytes(16);
const data = 'Sensitive information';

const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
let encrypted = cipher.update(data, 'utf8', 'hex');
encrypted += cipher.final('hex');
console.log('Encrypted:', encrypted);

const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
decrypted += decipher.final('utf8');
console.log('Decrypted:', decrypted);

Benefit: Fast. AES-256 can encrypt gigabytes per second on modern hardware. Perfect for encrypting files, database fields, or disk volumes.

Cost: Key distribution. Both parties need the same secret key. How do you share it securely? If you send it over the network, anyone intercepting that transmission owns your encryption. This is the fundamental problem symmetric encryption cannot solve by itself.

Asymmetric encryption

Two keys. The public key encrypts. The private key decrypts. You publish the public key openly. The private key never leaves your server.

Js
const crypto = require('crypto');

const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', {
  modulusLength: 2048,
});

const data = 'Sensitive information';

const encrypted = crypto.publicEncrypt(publicKey, Buffer.from(data, 'utf8')).toString('base64');
console.log('Encrypted:', encrypted);

const decrypted = crypto.privateDecrypt(privateKey, Buffer.from(encrypted, 'base64')).toString('utf8');
console.log('Decrypted:', decrypted);

Benefit: No shared secret. You can encrypt data for someone without ever exchanging a secret key. This also enables digital signatures: sign with your private key, anyone can verify with your public key.

Cost: Slow. RSA encryption is roughly 1000x slower than AES. You cannot practically encrypt large files with it. And the encrypted output is larger than the input.

When to use which

Symmetric is right for:

  • Encrypting data at rest (files, databases, backups)
  • Encrypting data in transit after a secure channel is established
  • Any scenario where both parties already share a secret

Asymmetric is right for:

  • Establishing a secure channel between strangers (TLS handshake)
  • Digital signatures and certificate verification
  • Key exchange protocols

How the real world uses both

TLS, the protocol that secures every HTTPS connection, uses both. The handshake uses asymmetric encryption to securely exchange a symmetric session key. Then all actual data flows over symmetric encryption.

This hybrid approach gets you the best of both worlds: the key-exchange safety of asymmetric and the speed of symmetric. Almost every secure protocol works this way.

Keep reading