Security
Lesson 6 of 8About 4 min readSuggest an edit

Cryptography for engineers

You rarely need the mathematics, but you do need to pick the right tool, use it through a safe API and look after the keys. Most real failures come from misuse, not broken algorithms.

Four different jobs

Tool Gives you Key Example
Hash a fixed-size fingerprint none SHA-256 of a file
MAC integrity and authenticity shared secret HMAC-SHA256 on a webhook
Signature integrity, authenticity, public verification private to sign, public to verify Ed25519 on a release
Encryption confidentiality secret or key pair AES-GCM on a stored card token

A hash is one-way and anyone can compute it, so it proves nothing about who produced the data. Passwords need a slow, salted password hash, covered in the authentication lesson, not a plain hash.

A MAC (message authentication code) proves that someone holding the shared key produced the message and that it has not changed. Compare MACs in constant time (hmac.compare_digest in Python) so timing reveals nothing.

A digital signature uses a key pair instead: only the private key can sign, anyone with the public key can verify, and verifiers cannot forge messages.

Encryption hides content. On its own it does not stop tampering, so prefer authenticated encryption.

Symmetric and asymmetric

Symmetric encryption uses one shared key for both directions. It is fast and suits bulk data. AES-GCM and ChaCha20-Poly1305 are authenticated modes: decryption fails if the ciphertext or its associated data was altered.

Asymmetric cryptography uses a public and private key pair. RSA and elliptic-curve schemes (X25519 for key agreement, Ed25519 for signatures) handle key exchange and signing, not bulk data. Real systems combine them: asymmetric crypto agrees on or wraps a symmetric key, and the symmetric key encrypts the data.

Use vetted libraries and high-level APIs

Never invent your own algorithm, mode or protocol. Choose libraries whose high-level APIs make safe choices for you, such as libsodium or Google Tink. In Python, the cryptography package offers authenticated encryption in a few calls:

import os
from cryptography.hazmat.primitives.ciphers.aead import AESGCM

key = AESGCM.generate_key(bit_length=256)  # load from a KMS
aead = AESGCM(key)

nonce = os.urandom(12)                     # fresh every time
ct = aead.encrypt(nonce, b"4111 ...", b"user:42")
# store nonce with ct (not secret)

pt = aead.decrypt(nonce, ct, b"user:42")   # raises if altered

The associated data (b"user:42") is authenticated but not encrypted; it ties the ciphertext to one record.

Randomness

Keys, nonces, tokens and session ids need a cryptographically secure random number generator (CSPRNG): secrets or os.urandom in Python, crypto.randomBytes in Node.js, crypto.getRandomValues in browsers. Math.random and random.random are predictable; never use them for security.

Key management and rotation

  • Keep keys in a key management service (KMS) or hardware security module, not in code or config files.
  • Use envelope encryption: data is encrypted with a data key, and the data key is encrypted by a master key that never leaves the KMS.
  • Give each purpose and environment its own key.
  • Plan rotation from the start: record a key id with each ciphertext so old data can still be decrypted while new data uses the new key.

TLS

TLS protects data in transit, authenticating the server and encrypting the connection. Use TLS 1.2 or later, with 1.3 preferred, and let your platform or load balancer choose cipher suites. Redirect HTTP to HTTPS and send an HSTS header. Never disable certificate verification in clients. Internal service-to-service traffic deserves TLS too.

Common mistakes

  • ECB mode: identical plaintext blocks encrypt to identical ciphertext blocks, so patterns stay visible.
  • Reusing a nonce with the same key in AES-GCM: this can reveal the plaintexts and let an attacker forge messages.
  • Hard-coded keys in source, images or mobile apps: anyone with the artefact has the key.

Habits

  • Name the property you need (confidentiality, integrity, authenticity) before picking a tool.
  • Generate every secret value with a CSPRNG.
  • Store keys in a KMS and rehearse rotation.
  • Get crypto code reviewed by someone who knows the library.

Next: Security in the development lifecycle

Building security into requirements, review, automated scanning, testing and the way you prioritise fixes.