Applied Cryptography and Key Management Questions
Selecting and applying cryptographic primitives correctly: symmetric and asymmetric encryption, hashing, digital signatures, key derivation, secure random number generation, and public key infrastructure. Covers key lifecycle management, key exchange and distribution, choosing appropriate algorithms for a given constraint set including resource-constrained environments, and the forward-looking side of algorithm lifecycle: cryptographic agility and algorithm-migration strategy, forward secrecy, and the post-quantum cryptography transition and planning upgrades without breaking existing data or interoperability. The applied-crypto engineering layer, distinct from compliance-driven crypto standards.
What is a Key Management Service, and what does the full key-management lifecycle look like for symmetric and asymmetric keys in an enterprise environment? For each stage (generation, provisioning, storage/usage, rotation, revocation, archival, secure destruction), name concrete controls and automation options you'd expect a KMS or HSM to provide, and the audit/logging you'd want at each stage. Compare cloud-managed KMS, HSM-backed KMS, and self-hosted key stores (like HashiCorp Vault) from an operational and decision-criteria standpoint: when would you reach for each?
Sample Answer
Direct answer
A key-management service (KMS) generates, stores, and controls the use of cryptographic keys without ever handing raw key material to the applications that use it: applications send data (or a wrapped key) and get back a result, never the key itself. Whether that KMS is a cloud-managed service, an on-premises hardware security module (HSM), or a self-hosted secrets manager is a decision about who controls the boundary the key never crosses, not about whether encryption happens.
The key lifecycle, stage by stage (the stages are the same for symmetric and asymmetric keys; only the storage/usage operations differ)
| Stage | What happens | Controls and automation | Audit and logging |
|---|---|---|---|
| Generation | Key material is created with a cryptographically secure random number generator, ideally inside the HSM/KMS boundary | Hardware random-number generator inside the HSM; enforced key-length/algorithm policy | Who requested generation, for what purpose, and the resulting key identifier and version |
| Provisioning | The key is made available to authorized services | Access policy binding the key to specific roles/services (least privilege); for asymmetric keys, distributing only the public half where possible | Every policy grant or change |
| Storage and usage | The key sits encrypted at rest, often wrapped by a KMS/HSM master key, and is used via API calls (encrypt/decrypt/sign/verify) rather than exported | Usage restricted to specific operations (a signing key that can only sign, never decrypt); rate limiting and anomaly detection on usage volume | Every single use: caller identity, operation, timestamp, and key version |
| Rotation | The active key is periodically replaced by a new version while old versions remain available to decrypt or verify data they already protected | Automated rotation schedules; for symmetric data-encryption keys, a key-encryption-key hierarchy so rotating the top key does not require touching the data | Rotation events and which version range remains valid for verification |
| Revocation | A key is marked untrusted before its normal retirement, typically on suspected compromise | Immediate propagation to every relying party's trust/verification list | Revocation reason, initiator, and propagation confirmation across systems |
| Archival | Retired keys are kept, encrypted, for as long as needed to decrypt or verify historical data, but are no longer used for new operations | Read-only access policy; a separate, more restrictive storage tier | Every archival access, since it is rarer and more suspicious by default |
| Secure destruction | Key material is irrecoverably deleted; cryptographic shredding is often the practical version of "destroying" data you cannot otherwise find and erase | Dual control (two-person authorization) before permanent deletion; a mandatory waiting or appeal window | The destruction request, dual-control approvals, and a permanent record that the key existed and was destroyed on a given date |
Comparing the three approaches
| Option | Where the key boundary lives | Best when |
|---|---|---|
| Cloud-managed KMS | Inside the cloud provider's infrastructure; you control policy, not physical hardware | You want low operational overhead and tight integration with the rest of a cloud provider's services, and accept its shared-responsibility model for the hardware layer |
| HSM-backed KMS | A dedicated hardware module, often validated against FIPS 140-3 (the current U.S. federal cryptographic-module standard; FIPS 140-2 certificates move to historical status by September 2026) | Regulatory or contractual requirements demand a specific, auditable hardware assurance level, or you need "hold your own key" control where the provider never sees the key at all |
| Self-hosted key store (for example HashiCorp Vault) | Entirely within your own infrastructure | You need full control over the software stack and deployment model, operate outside a single cloud provider, or have requirements a shared multi-tenant service cannot satisfy, at the cost of owning the operational burden yourself |
Worked example
A data platform storing per-tenant records typically holds a small number of key-encryption keys in the KMS/HSM (one or a handful per tenant, or a shared key with per-tenant data-encryption keys) and generates a fresh data-encryption key per object or per batch; only that small key ever needs to be sent to the KMS to unwrap, so the KMS's per-operation cost stays proportional to the number of distinct data-encryption keys, not the volume of underlying data.
Trade-offs and pitfalls
Do not conflate "we use a cloud KMS" with "we have a FIPS 140-3 validated system": the certification applies to a specific hardware/firmware module at a specific validation level (1 through 4), not automatically to every service built on top of it or to your own key-management practices. The most common real-world gap is not choosing the wrong option above, it is under-provisioning the audit-logging stage: if you cannot answer who used a key, when, and for what, after the fact, the KMS choice does not matter.
Why can't you just hash a password with SHA-256 and call it done? Walk through what a key derivation function actually is (how it differs from a plain hash or a PRF) and compare PBKDF2, bcrypt, scrypt, and Argon2 as password-storage choices: the core mechanism each relies on (iteration count vs memory hardness), typical parameter knobs, and strengths/weaknesses. Then explain how the calculus changes when you're deriving a session key from an already-random shared secret instead of a low-entropy password, and where HKDF fits that case.
Sample Answer
Direct answer
A plain hash like SHA-256 is deliberately fast and has no built-in salt, so two users with the same password get identical hashes, and an attacker holding stolen hashes can try billions of guesses per second on off-the-shelf hardware. A key derivation function (KDF) exists to do the opposite: turn a secret (a password, or an existing high-entropy secret) into cryptographic key material through a process that is either deliberately expensive, for password-based KDFs, to slow down guessing, or that safely spreads entropy into independent-looking keys, for a secret that is already random. PBKDF2, bcrypt, scrypt, and Argon2 are password-hashing KDFs; HKDF is built for the second case.
KDF vs hash vs pseudorandom function (PRF)
- A cryptographic hash function (SHA-256) maps arbitrary input to a fixed-size output, deterministically and quickly, with no secret key. Good for integrity checks; bad for password storage precisely because it is fast.
- A pseudorandom function (PRF), commonly HMAC-SHA256, is a keyed function whose output is computationally indistinguishable from a truly random function's output to anyone without the key. PRFs are building blocks, not complete answers: they say nothing about work factor or memory cost.
- A KDF composes a hash or PRF with an explicit strategy (iteration, memory hardness, or entropy extraction/expansion) to solve "slow this down for guessing resistance" or "expand this safely."
Comparing the four password-hashing KDFs
| Algorithm | Core mechanism | Typical knobs | Strength | Weakness |
|---|---|---|---|---|
| PBKDF2 | Iterates a PRF (usually HMAC-SHA256) c times | Iteration count only | Simple, standardized in NIST SP 800-132, widely available in FIPS-validated libraries | Needs almost no memory, so custom hardware (ASICs, GPUs) can run millions of cheap parallel guesses |
| bcrypt | Repeated Blowfish key schedule | Cost factor (rounds = 2^cost) | Decades of scrutiny, resists naive GPU ports better than PBKDF2 | Fixed, small (roughly 4 KB) memory footprint; silently truncates passwords past 72 bytes |
| scrypt | Sequential memory-hard mixing | Memory/CPU cost N, block size r, parallelism p | True memory hardness (RFC 7914), first widely deployed | More complex to tune correctly; mostly superseded by Argon2 for new work |
| Argon2 | Memory-hard, tunable in three dimensions | Memory m, iterations t, parallelism p | Winner of the 2015 Password Hashing Competition, documented in RFC 9106, three variants for different threat models | Needs careful parameter tuning per target hardware |
The line that matters most: PBKDF2 and bcrypt scale cost mainly by adding sequential compute, which cheap, highly parallel hardware absorbs well. scrypt and Argon2 scale cost by requiring a large memory footprint per guess, and memory is expensive to duplicate across thousands of parallel attempts, which is why they resist GPU/ASIC cracking far better per unit of legitimate server CPU time spent.
When the input is already random: HKDF
Once you have a high-entropy shared secret, for example the output of an ECDHE key exchange, you have no guessing problem to defend against; you have an "I need several independent-looking keys from one secret" problem (a separate encryption key and a MAC key, or per-direction keys). Deliberately slowing that down the way PBKDF2/Argon2 do would only add latency with no security benefit, since there is no offline dictionary attack to resist. HMAC-based key derivation function (HKDF, RFC 5869) is built for exactly this: an "extract" step concentrates the input's entropy into a fixed-length pseudorandom key using HMAC, then an "expand" step derives as much labeled output keying material as needed, bound to a context string so an encryption key and a MAC key derived from the same secret cannot be confused with each other.
Worked example
Deriving 64 bytes of key material (a 32-byte AES key plus a 32-byte HMAC key) from a 32-byte ECDHE shared secret with HKDF-SHA256 is one Expand call producing two concatenated 32-byte outputs. HKDF-SHA256 has a hard ceiling from its own specification: the expand step can produce at most 255 times the hash length, which for SHA-256 (32-byte output) is
255×32=8160 bytes
Deriving a handful of session keys never comes close to that ceiling, which underlines the point: HKDF is built to expand cheaply, not to resist guessing.
Trade-offs and pitfalls
- Argon2id is the current default recommendation over PBKDF2 or bcrypt precisely because of the memory-hardness gap above.
- Using a password KDF where you actually have a random shared secret wastes CPU and adds latency for no security gain; using HKDF where you actually have a low-entropy password gives an attacker no additional cost at all, since HKDF has no configurable work factor.
- Never build a KDF out of raw hash calls yourself; use the vetted PBKDF2/bcrypt/scrypt/Argon2/HKDF implementation in your language's standard cryptography library.
Describe the core components and trust model of an enterprise Public Key Infrastructure: root CA, intermediate CAs, issuing CAs, certificate profiles and validity periods, registration authorities, and the strategies (offline root, short-lived certs, cross-certification) used to limit blast radius if a CA is compromised. Then walk through what actually happens end to end for one certificate: how it's requested and issued (CSR, CA validation), how a client validates the resulting chain (chain verification, hostname checks), and how automated issuance (e.g. Let's Encrypt / ACME) changes that story at scale.
Sample Answer
Direct answer
A production public key infrastructure (PKI) is a tree of trust: an offline root certificate authority (CA) signs one or a few intermediate CAs, which in turn sign the issuing CAs that actually hand out end-entity certificates. Nobody trusts an end-entity certificate directly; they trust it because it chains up to a root their software already trusts.
Trust model and components
- Root CA: the ultimate trust anchor, pre-installed in operating systems' and browsers' trust stores. Because compromising it would let an attacker mint a trusted certificate for anything, it is kept offline (air-gapped, powered on only to sign new intermediates) and used as rarely as possible.
- Intermediate CA: signed by the root, does the actual day-to-day signing directly or through issuing CAs beneath it. Splitting root from intermediate means a compromised or misused intermediate can be revoked without touching the root already baked into every trust store, avoiding a mass client update.
- Issuing CA: the online intermediate (or sub-CA) that actually processes certificate requests. Large organizations often run separate issuing CAs per purpose (TLS server certs, code-signing certs, client-auth certs), so a problem in one issuing path does not force revoking every certificate type at once.
- Registration authority (RA): the component, sometimes separate, sometimes folded into the issuing CA, that verifies a requester actually controls the domain or identity being certified before the CA signs anything.
- Certificate profiles and validity periods: a profile defines the fields and extensions a given certificate type must carry (key usage, extended key usage, subject alternative names). Shorter validity periods shrink the window a compromised or mis-issued certificate stays dangerous: the CA/Browser Forum's baseline requirements capped public web TLS certificates at 398 days for years, but a phased reduction already dropped that ceiling to 200 days in March 2026, with 100 days due in March 2027 and 47 days by March 2029.
Limiting blast radius if a CA is compromised
- Offline root: the root's private key never touches a network-connected machine, so remote compromise of issuing infrastructure cannot reach it directly.
- Short-lived certificates: if certificates expire in days rather than years, a compromised issuing CA's damage window is bounded by how quickly you detect and revoke it, and even undetected mis-issuance ages out fast.
- Cross-certification: having two independent CAs certify the same intermediate, or maintaining alternate trusted paths, means a single CA's revocation does not instantly break every relying party, giving a rollover path instead of a hard outage.
End-to-end walkthrough for one certificate
- Request and issuance: the requester generates a key pair and a certificate signing request (CSR), a self-signed message asserting "I hold the private key matching this public key, and I am requesting a certificate for this identity." The RA/CA validates control of the domain (a DNS record, an HTTP file, or an out-of-band check) or identity, then the issuing CA signs the CSR's public key and identity into a certificate.
- Client validation: a client receiving the certificate walks the chain up to a trusted root (chain verification), checks the certificate has not expired or been revoked, and checks the hostname it connected to matches a name listed in the certificate (hostname/Subject Alternative Name check). Any one of those failing should hard-fail the connection.
- Automated issuance at scale: the Automatic Certificate Management Environment (ACME) protocol, used by Let's Encrypt and most modern CAs, replaces manual CSR handling with an API: the client proves domain control programmatically (an HTTP or DNS challenge) and gets a certificate issued and renewed automatically, often on a 90-day lifetime. This is what makes short-lived certificates operationally viable at scale; doing this by hand across a large fleet would be a full-time job, but ACME turns it into unattended automation.
Worked example
example.com's certificate might be signed by "Acme Issuing CA G2," which is signed by "Acme Intermediate CA," which is signed by the offline "Acme Root CA X1" baked into an operating system's trust store; verifying the chain means checking each of those two signatures in turn before trusting example.com at all.
Trade-offs and pitfalls
Relying only on the default trust-store setup without your own operational monitoring for renewal and revocation is exactly what causes expired-certificate outages. OCSP stapling (the server proactively attaches a signed revocation-status response) exists because live client-side OCSP lookups add latency and leak browsing metadata to the CA; understanding why matters more than memorizing the acronym.
Explain the cryptographic differences between RSA key exchange and ECDHE (Elliptic Curve Diffie-Hellman Ephemeral) in TLS. Specifically, how does each impact perfect forward secrecy, and what are the consequences if the server's long-term private key is later compromised? What server configuration changes would you make to prioritize forward secrecy, and why?
Sample Answer
Direct answer
Static RSA key exchange lets the client encrypt the actual session secret directly under the server's long-term RSA public key, so anyone who later obtains the server's private key can decrypt every session ever recorded under it. ECDHE generates a fresh, temporary elliptic-curve Diffie-Hellman key pair for every handshake and derives the session key from that ephemeral exchange instead, so the server's long-term key never directly touches the session secret, and stealing it later reveals nothing about past sessions, which is exactly what forward secrecy means.
Mechanics
- RSA key exchange: the client generates a random pre-master secret, encrypts it with the server's RSA public key taken from its certificate, and sends it over. Only the private key can decrypt it, so this both establishes the shared secret and implicitly authenticates the server, but one long-term key is doing both jobs for every session, forever.
- Elliptic-Curve Diffie-Hellman Ephemeral (ECDHE): the server generates a fresh elliptic-curve key pair for this handshake only, sends the public half, and the client does the same; both sides compute the same shared secret from their own private half and the other's public half via elliptic-curve Diffie-Hellman. The server's long-term certificate key is used separately, only to sign the handshake and prove identity, never to encrypt the shared secret directly.
Impact on forward secrecy
RSA key exchange has none: the pre-master secret is only ever protected by the server's one long-term private key, so compromising that key at any later point retroactively exposes every session ever recorded that used it. ECDHE provides forward secrecy by construction: each session's ephemeral key pair is generated fresh and discarded after the handshake, so it is never derivable from the long-term signing key, and a future compromise of that key reveals nothing about past sessions' ephemeral keys, which no longer exist anywhere to be recovered.
Consequences of a later server private-key compromise
- Under RSA key exchange: catastrophic and retroactive. An adversary who recorded encrypted traffic at any point in the past and later obtains the private key can decrypt all of it, precisely the harvest-now-decrypt-later pattern.
- Under ECDHE: the compromised long-term key lets an attacker impersonate the server going forward, since they can now sign a fraudulent handshake and pass authentication, which is serious, but it does not expose any previously recorded session traffic, since that traffic's confidentiality never depended on the long-term key in the first place.
Server configuration changes to prioritize forward secrecy
- Remove RSA key-transport cipher suites from the server's negotiated suite list entirely rather than merely deprioritizing them, since a downgrade-capable client or a misconfigured negotiation could otherwise still select the weaker option.
- Prefer, and where the deployment allows it require, TLS 1.3, which removes static RSA key exchange from the protocol entirely, so this class of misconfiguration cannot happen at all rather than merely being avoided through careful cipher-suite ordering in TLS 1.2.
- If TLS 1.2 must still be supported for compatibility, explicitly configure the cipher-suite priority list so ECDHE-based suites are preferred over any suite offering only static RSA key transport. Note that RSA can still appear in an ECDHE suite name as the signature algorithm, for example ECDHE_RSA, which is fine, since only the key-exchange component matters here. Periodically re-verify the live negotiated configuration with an external TLS scan, not just a config-file review, since server software upgrades or configuration drift can silently reintroduce a deprioritized suite.
Trade-offs and pitfalls
Separate which part of the exchange the server's long-term key is doing, encrypting the actual session secret versus just signing a proof of identity, since that distinction is exactly where the forward-secrecy guarantee lives or does not. Simply deprioritizing a weak cipher suite in a configuration file is not the same guarantee as the protocol removing it entirely; treat TLS 1.3 adoption as the more durable fix.
Describe the purpose of a salt in password-based key derivation: what properties it needs (uniqueness, length, randomness), where it should be stored relative to the derived hash, and the operational risks of reusing or omitting it at scale. Then explain the difference between a salt and a pepper: how does adding a server-side secret pepper change the threat model for offline attacks, and what controls does protecting a pepper actually require?
Sample Answer
Direct answer
A salt is a unique, random, non-secret value stored alongside each password hash so identical passwords never produce identical stored hashes and precomputed lookup tables (rainbow tables) become useless. A pepper is a separate, secret value, shared across all users and stored outside the database, that adds a layer an attacker who only stole the database, and not the pepper's separate storage, cannot reproduce at all.
Salt properties
- Uniqueness: every stored hash gets its own salt, so no two hashes can ever be compared or looked up in a shared precomputed table, even if two users chose the same password.
- Length and randomness: generated fresh with a cryptographically secure random number generator, long enough (16 bytes is a common minimum) that collisions across an entire user base are effectively impossible.
- Storage: the salt is not secret and is stored right alongside the derived hash, often concatenated into the same stored string as most KDF libraries' output format does, because verification needs it: a login attempt cannot be checked without knowing which salt was used.
Operational risks of reusing or omitting a salt at scale
Reusing one salt across many users collapses back to the pre-salt world for that group: identical passwords produce identical hashes again, so one cracked hash cracks every account sharing that password. Omitting a salt entirely makes precomputed rainbow-table attacks viable against an entire user base at once, and is the single most common real-world password-storage mistake salting exists to prevent.
Salt vs pepper
A pepper adds an ingredient a salt deliberately lacks: it is the same value for every user, unlike a salt, and it is never stored in the same place as the password hashes, typically in application configuration, a secrets manager, or a hardware security module (HSM), specifically so that a database breach alone, a SQL injection or a stolen backup, does not hand an attacker everything needed to attempt offline cracking.
How a pepper changes the threat model
Without a pepper, stealing the password-hash database is sufficient to start an offline brute-force or dictionary attack immediately. With a pepper, the attacker also needs to compromise wherever the pepper is stored, a genuinely separate system with its own access controls, before offline attacks become possible at all; a database-only breach becomes far less immediately damaging.
Controls a pepper actually requires
A pepper only helps if it is genuinely harder to steal than the database: its own access control (ideally an HSM/KMS-backed secret, not an environment variable sitting next to application code that also has database access), its own rotation plan (rotating a pepper means re-verifying and re-deriving every stored hash, a real migration, not a config change), and monitoring, since a pepper stored in the same place, or reachable via the same compromise path, as the database it protects provides no real additional security at all.
Unlock Full Question Bank
Get access to all 8 Applied Cryptography and Key Management interview questions and detailed answers.
Sign in to ContinueJoin thousands of developers preparing for their dream job.