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.