Cryptography Fundamentals Questions
Core concepts and vocabulary of cryptography: confidentiality, integrity, authentication, and non-repudiation; the difference between symmetric and asymmetric primitives; and how standard algorithms, libraries, and protocols fit together. Covers threat models, common standards, and applying primitives and cryptographic libraries correctly to real-world security problems. The entry point for the cryptography track.
Walk through the hybrid (envelope) encryption pattern for protecting a large file or a message sent to multiple recipients: how the symmetric session key is generated, how it is wrapped with each recipient's public key, what integrity/authenticity protection you'd add, and how you'd support forward secrecy for recipients if the file might be re-shared later.
Sample Answer
Direct answer
Hybrid (envelope) encryption solves "encrypt this once for many recipients" by splitting the
job in two: generate one random symmetric key to encrypt the actual data, then encrypt
("wrap") that small key separately for each recipient using their public key. The body is
encrypted once; only the tiny key gets encrypted N times.
Structured elaboration
- Generate the session key. Pull a fresh, random key from a CSPRNG (cryptographically
secure pseudo-random number generator), for example a 256-bit AES key. Call this the
Data Encryption Key (DEK). It exists only for this file/message. - Encrypt the payload once with an AEAD cipher. Use the DEK with AES-256-GCM or
XChaCha20-Poly1305 and a fresh nonce. AEAD (authenticated encryption with associated
data) gives you confidentiality (the data is unreadable without the key) and
integrity/authenticity (a forged or tampered ciphertext fails to decrypt) in one pass,
which directly answers the "what integrity protection" part: you do not bolt on a
separate MAC, the AEAD tag already is one. - Wrap the DEK per recipient. For each recipient, encrypt the small DEK with that
recipient's public key: RSA-OAEP is the simple choice, or (better for many recipients or
small devices) an ECDH-based wrap, ECIES-style: derive a one-time wrapping key from
ECDH(sender_ephemeral, recipient_public) and use it to encrypt the DEK. Store one small
wrapped-key blob per recipient next to the single ciphertext body. This is the
multi-recipient piece: the expensive part (encrypting the file) happens once; only the
cheap part (wrapping ~32 bytes) repeats per recipient, so adding a recipient never means
re-encrypting the file. - Forward secrecy for later re-shares. A plain RSA-OAEP wrap is not forward secret: if
the recipient's long-term private key leaks years later, every DEK ever wrapped for them
can be recovered and every past file decrypted retroactively. If a file might be
re-shared later, wrap with a fresh ephemeral key exchange per share event instead of a
static wrap: generate a one-time ephemeral key pair, run ECDH against the recipient's
long-term public key, derive the wrap key through a KDF (key derivation function, e.g.
HKDF) over that shared secret, and never persist the ephemeral private key anywhere.
Each share event is now cryptographically independent: compromising one wrap does not
expose any other share of the same file, because there is no single long-lived
server-side wrapping secret that unlocks all of them at once. - Avoid full re-encryption on re-share. None of this requires touching the ciphertext
body again. Keep the DEK and the AEAD ciphertext exactly as they are; a re-share only
adds a new wrapped-DEK entry for the new recipient (fresh ephemeral wrap as in step 4).
You only rotate the DEK itself, which does mean re-encrypting the body, if you need to
revoke an earlier recipient's access to future reads.
Worked example
A 2 GB backup file needs to go to 3 recipients. You generate one 256-bit DEK, run AES-256-GCM
once over the 2 GB (one pass over the large data), then wrap that same 32-byte DEK three
times, once per recipient's public key. Total asymmetric operations: 3, regardless of file
size. If a 4th person needs access next month, you do one more 32-byte wrap using a fresh
ephemeral exchange; the 2 GB ciphertext is never touched again.
Trade-offs & pitfalls
- RSA-OAEP wrapping is simpler to implement and audit; ECDH-based wrapping is smaller and
cheaper per recipient, which matters more as recipient count grows, but adds an extra
ephemeral-key-handling step. - This exact pattern is what OpenPGP's multi-recipient encryption and cloud KMS "envelope
encryption" (wrapping a data key with a master key) both do. - Common mistake: reusing the AEAD nonce across re-encryptions of the same DEK, or reusing
one static wrap key across shares when forward secrecy was actually required. Both quietly
remove the protection the design was supposed to provide.
Your organization still relies on SHA-1 in legacy components including certificate signatures and internal git repositories. Create a phased migration plan to stronger hashes (SHA-256 or better) that minimizes downtime, covers certificate replacement and repository migration, addresses interoperability with older clients, and verifies successful migration.
Sample Answer
Framing
SHA-1 (Secure Hash Algorithm 1) has a practically demonstrated collision break: attackers have published real pairs of distinct inputs producing the same hash, which matters enormously for certificate signatures (a certificate authority's signature over a certificate is only trustworthy if nobody could have engineered a colliding, malicious certificate with the same signature) and matters somewhat differently for a version-control system, where hashes are primarily content-addressing identifiers, not signatures over untrusted third-party input, but a maliciously crafted collision could still let an attacker substitute code silently. The migration has to run on two independent tracks with different urgency, plus a compatibility bridge for anything that can't move immediately.
Phased plan
- Inventory and freeze new usage. Find every place SHA-1 is used: certificate signing requests still being issued with SHA-1, internal certificate authorities configured to sign with it, git repositories, and any code computing SHA-1 for reasons other than pure legacy compatibility. Immediately stop issuing anything new with SHA-1, every new certificate gets a SHA-256 signature, this alone is low-risk and shrinks the problem going forward.
- Certificate replacement, done by criticality. Re-issue certificates in order of exposure: externally-facing services first (least time for an attacker to have obtained a colliding forgery in the wild, since publicly trusted certificate authorities stopped issuing SHA-1 certificates industry-wide years ago), then internal services with their own private certificate authority. For each certificate, reissue with a SHA-256 (or stronger) signature, deploy to the service, and confirm it serves the new chain before revoking the old one, not the other way around, to avoid an outage window with no valid certificate at all.
- Interoperability with older clients. Some very old clients may not support SHA-256-signed certificate chains. Handle this the same way any protocol version deprecation is handled: identify which specific clients are actually still connecting (from real traffic logs, not assumption), give them a defined, communicated end-of-support date, and only keep a SHA-1 fallback path alive for that dwindling population, with monitoring on its usage so you know when it's safe to remove.
- Repository migration. For internal git repositories still keyed by SHA-1 object identifiers, the practical mitigation already in wide use is a hardened SHA-1 implementation that detects known collision-attack patterns (this is what major hosting platforms adopted after the first public collision was demonstrated) rather than an immediate wholesale rehash, since git's own transition to a stronger hash is a larger, longer-running effort tracked by the git project itself; the near-term action for an internal deployment is ensuring the collision-detecting variant is actually in use, and tracking the upstream migration path for the longer term.
- Verification. Confirm success with evidence, not assumption: scan all active certificates for signature algorithm, monitor certificate authority issuance logs to confirm zero new SHA-1 signatures, and run a hash-algorithm audit against the code and configuration inventory from step 1 to catch anything missed.
Trade-offs and pitfalls
The riskiest failure mode in this kind of migration isn't SHA-1 itself, it's a broken rollout: revoking an old certificate before confirming the new one is deployed and trusted causes a real outage, and rushing repository rehashing without coordinating with every consumer of those commit hashes (build systems, deployment pipelines, external mirrors) can silently break more than it fixes. Sequence certificate work by exposure and treat the legacy-client interoperability period as a tracked, time-boxed exception with an actual removal date, not a permanent fallback that quietly never gets revisited.
Compare Message Authentication Codes (like HMAC or CMAC) with digital signatures: when would you use each for authentication and integrity, and how do they differ in non-repudiation, key management (shared vs asymmetric key), and performance in an enterprise setting?
Sample Answer
Direct answer
Use a MAC (like HMAC or CMAC) when both sides already share a secret key and you only need to
prove the message wasn't tampered with between two mutually-trusting parties. Use a digital
signature when you need non-repudiation, proof that a specific party and no one else produced
it, or when many independent parties need to verify without ever holding a shared secret.
Structured elaboration
- Non-repudiation: a MAC is computed with a shared key, so either party who holds that
key could have produced it; the receiver themselves is technically capable of forging a
valid MAC, which means a MAC can never prove who specifically created a message, even to
itself. A digital signature is produced with a private key only the signer holds; anyone
with the public key can verify it came from that specific private key, giving genuine
non-repudiation, the signer cannot credibly deny having signed it. - Key management: a MAC needs the same secret key securely distributed to every party who
must verify, which does not scale well once there are many independent verifiers. A
signature scheme needs one private key held by the signer and an openly distributable public
key; any number of parties can verify without any of them holding a secret at all, which is
why signatures fit enterprise settings with many downstream consumers (software distribution,
document signing across organizations, certificate chains). - Performance: HMAC (built from a hash function) and CMAC (built from a block cipher) are
both fast, symmetric-key operations. Signing with RSA or ECDSA costs more than computing a
MAC (it involves genuine asymmetric-key math), though ECDSA signing is considerably cheaper
than RSA signing at an equivalent security level; verification is typically the cheaper
half of a signature scheme.
Worked example
Two microservices inside the same trust boundary, sharing a secret deployed via the same
secrets manager, want to confirm requests between them are unmodified: HMAC is the right
choice, since both sides already trust each other and share the key, and no outside party
ever needs to verify these requests. A software vendor shipping an update that thousands of
independent customer machines must verify came from that vendor, and no one else, needs a
digital signature: there is no shared secret between the vendor and every customer, and only
the vendor's private key should be able to produce a valid signature.
Trade-offs & pitfalls
- Using a MAC where verification needs to happen outside the trusted pair (say, a
third-party auditor) quietly breaks the "who could have produced this" guarantee that the
scenario actually needed. - Using a signature purely for internal service-to-service integrity checks works but pays an
unnecessary performance and key-management cost when a shared-key MAC would have been
sufficient.
A microservice needs to encrypt small high-frequency messages with minimal latency. Evaluate trade-offs between using symmetric AEAD (AES-GCM), hybrid encryption per recipient, or public-key authenticated encryption. Consider throughput, key management complexity, bandwidth, and security properties (confidentiality, authentication). Recommend an approach and justify.
Sample Answer
Direct answer
For small, high-frequency messages, use symmetric authenticated encryption with associated data
(AEAD), such as AES in Galois/Counter Mode (AES-GCM) or ChaCha20-Poly1305, on a per-recipient
session key that was established once via a public-key exchange, not per message. Doing the
expensive public-key operation on every message is the one option that does not scale; doing it
once per session and then paying only symmetric-cipher cost per message is the standard answer to
this trade-off.
Structured elaboration
| Option | Per-message cost | Key management | Bandwidth overhead |
|---|---|---|---|
| Symmetric AEAD with a shared session key | One block-cipher pass plus a fixed 16-byte tag | Needs a session key already established and rotated | Smallest: nonce (12 bytes) + 16-byte tag |
| Hybrid: wrap a fresh symmetric key per message with the recipient's public key | Adds one public-key encryption per message on top of the symmetric pass | Simplest trust model (only public keys needed) but a new wrapped-key blob every message | Largest: a public-key-sized blob (hundreds of bytes) added to every message |
| Public-key authenticated encryption directly on the payload | A public-key operation sized to the whole message, not just a key | Simplest key distribution | Largest and slowest; public-key primitives are not built for bulk data |
- Confidentiality and authentication. AEAD gives you both in one pass: the tag fails to verify
if either the ciphertext or any associated data was altered, so you do not need a separate
Message Authentication Code (MAC). - Key establishment. Do the public-key work exactly once per session, using an
Elliptic-Curve Diffie-Hellman (ECDH) exchange, and derive the AEAD key from that shared secret
with a Key Derivation Function (KDF) such as HKDF. Rotate the session key on a schedule (minutes
to hours, depending on how sensitive the traffic is) rather than per message. - Nonce discipline. AES-GCM's security depends entirely on never reusing a nonce under the
same key. At high message rates, a per-connection counter is safer than relying on randomness
alone; if that is operationally awkward, use a nonce-misuse-resistant mode (AES-GCM-SIV) as
insurance rather than as the primary design.
Worked example
A checkout service sends roughly one small event per user action to a downstream fraud-scoring
service. Design: on connection setup, run ECDH once between the two services to get a shared
secret, derive a 256-bit AEAD key with HKDF, then for every event call
AESGCM(key).encrypt(nonce, event_bytes, aad=service_id) with a monotonically increasing 96-bit
counter as the nonce. Per-message cost is now one AES-GCM pass over a few hundred bytes and a
16-byte tag; the ECDH and HKDF steps run once per connection lifetime, not once per event, which is
exactly what keeps the per-message path cheap regardless of message volume.
Trade-offs & pitfalls
- Hybrid-per-message and public-key-per-message both add a public-key operation to the hot path;
at high frequency this dominates cost and is the wrong trade for latency-sensitive traffic. - A shared long-lived session key is only as strong as its rotation policy: an attacker who
compromises it can read every message encrypted under it until rotation, so weigh rotation
frequency against key-exchange overhead. - Common wrong turn: choosing hybrid encryption "for simplicity" without noticing that generating
and wrapping a fresh symmetric key every message reintroduces the exact public-key cost per
message you were trying to avoid.
State recommended key length guidance for common algorithms: AES (symmetric), RSA (classical public-key), and elliptic curve algorithms (ECDSA/ECDH). Explain why key length matters and what operational considerations (performance, lifespan, algorithm migration) influence your choice of length.
Sample Answer
Direct answer
Roughly: AES-128 or AES-256 for symmetric keys, at least RSA-2048 with RSA-3072 preferred for
longer-lived data, and a 256-bit elliptic curve (like P-256) for ECDSA/ECDH. These are not
interchangeable "bit strengths": because the underlying hard problems differ, RSA needs a
much larger key than AES or ECC to reach the same practical security level.
Structured elaboration
Key length matters because it determines how expensive the best known attack is. For a
symmetric cipher, the best general attack is brute force over the key space, so security
scales directly and exponentially with key bits. RSA's security instead rests on integer
factorization, which has sub-exponential algorithms (the General Number Field Sieve), so RSA
needs a much larger key to match a given symmetric strength. Elliptic-curve cryptography
relies on the discrete logarithm problem over an elliptic curve, which has no known
sub-exponential attack, so it reaches strong security with much smaller keys than RSA.
Roughly matched security levels (NIST SP 800-57 style guidance):
| Symmetric-equivalent strength | AES | RSA | ECC (ECDSA/ECDH) |
|---|---|---|---|
| ~128-bit | AES-128 | RSA-3072 | P-256 |
| ~192-bit | AES-192 | RSA-7680 | P-384 |
| ~256-bit | AES-256 | RSA-15360 | P-521 |
Operational considerations that influence the choice:
- Performance: RSA key generation and private-key operations get noticeably slower as key
size grows; ECC stays comparatively cheap even at higher security levels, which is why TLS
handshakes favor ECDHE over large-RSA key exchange today. - Lifespan: a key protecting data that must stay confidential for decades (a root CA, an
archival encryption key) should sit at a higher security margin than a short-lived TLS
session key, since attacker capability only improves over time. - Algorithm migration headroom: teams often deliberately keep some headroom above the
current minimum recommendation, so that a future algorithm migration (moving to a larger
key size, or off an algorithm entirely) can happen on a planned schedule rather than as an
emergency re-key after a break is announced.
Worked example
A document-signing service needs signatures that remain verifiable for 20-year regulatory
retention. A TLS session key, by contrast, only needs to resist attack for the minutes the
connection is open. Both could technically use "128-bit class" security today, but the
signing service deliberately picks RSA-3072 over RSA-2048 (or a 384-bit curve over a 256-bit
one) precisely because of the lifespan consideration: a 20-year window gives attacker capability
two decades to improve, so the team spends a bit more compute per signature now to buy margin
that a short-lived session key does not need.
Trade-offs & pitfalls
- RSA-2048 is still widely deployed and considered acceptable for most near-term use, but
guidance is trending toward RSA-3072 for anything expected to remain secure for many years;
treat any bare "RSA-2048 is fine forever" claim with suspicion. - Bumping AES from 128 to 256 bits has essentially no practical performance cost on modern
hardware (AES-NI accelerates both equally), so the "just use AES-256 to be safe" instinct is
cheap here in a way it is not for RSA.
Unlock Full Question Bank
Get access to all 41 Cryptography Fundamentals interview questions and detailed answers.
Sign in to ContinueJoin thousands of developers preparing for their dream job.