Question presented to candidate: "You need to store a customer's API key encrypted at rest, so your own service can decrypt and use it later — this is different from password hashing, where you never need the original back. What does Node's crypto module actually give you for that, and how do you know the encrypted data has not been tampered with?"
What a strong answer should cover:
- Node's
cryptomodule (built-in, backed by OpenSSL) covers three genuinely distinct concerns: hashing (one-way, for passwords — covered fully in its own dedicated question), reversible encryption/decryption (for data the application genuinely needs to recover later, like the API key in the prompt), and generating cryptographically secure random values (crypto.randomBytes, for tokens, salts, IVs). - 📌 Verified, not assumed: a real
createCipheriv/createDecipherivround trip using AES-256-GCM correctly encrypted and decrypted a plaintext string — and, critically, tampering with a single byte of the ciphertext and attempting to decrypt it with the unmodified authentication tag was rejected with a real thrown error, rather than silently returning corrupted or wrong plaintext. - 📌 The specific reason that tamper-rejection matters: AES-GCM is an authenticated encryption mode — it produces both ciphertext and an authentication tag, and decryption fails loudly if the ciphertext (or the tag) has been altered. A non-authenticated mode (plain AES-CBC, for instance) would decrypt tampered ciphertext into garbage plaintext with no error at all — a real, meaningful security difference, not a minor implementation detail.
- Encryption keys and IVs (initialization vectors) must be handled correctly: the key must be kept secret (never hardcoded in source, ideally from a secrets manager or environment variable); a fresh, random IV should be used for every encryption operation with the same key, since reusing an IV can catastrophically weaken many cipher modes' security guarantees.
- A precise answer distinguishes this reversible-encryption use case from password hashing (
scrypt/pbkdf2, covered in its own dedicated question, which is deliberately one-way) and fromzlibcompression (covered in its own dedicated question, which provides no confidentiality at all) — three genuinely different tools for three genuinely different problems, easily conflated under a vague "keep data secure" framing. crypto.randomBytes/crypto.randomUUIDprovide cryptographically secure randomness, suitable for security-sensitive values (session tokens, password-reset tokens) — unlikeMath.random(), which is not cryptographically secure and must never be used for anything security-sensitive.
Clarifying questions expected:
- "Does the application genuinely need to recover the original value later, or only verify a guess against it?" — the deciding factor between reversible encryption and one-way hashing.
- "Is the current implementation using an authenticated cipher mode (GCM), or an older, non-authenticated one?" — a real, meaningful security distinction worth checking explicitly.
Code / implementation expected: Yes — a real AES-256-GCM round trip, including the tamper-rejection demonstration, is the concrete, convincing proof of both correctness and the specific security property authenticated encryption provides.