Sikau

Project: A secure API gateway · Day 2 · about 40 min

Encrypted payloads

AES-GCM: confidentiality and tamper detection with a fresh IV per message.

Signed isn't secret

The signature proves who sent a request, but anyone on the path can still read it. AES-GCM encrypts the body *and* adds an authentication tag, so the ciphertext is unreadable without the key and any change makes decryption fail. One rule matters above all: never reuse an IV with the same key.

Encrypt and decrypt

async function aesKey(hexKey) {
  return crypto.subtle.importKey("raw", fromHex(hexKey), "AES-GCM", false, ["encrypt", "decrypt"]);
}

async function encrypt(hexKey, text, ivHex) {
  const iv = ivHex ? fromHex(ivHex) : crypto.getRandomValues(new Uint8Array(12)); // never reuse an IV
  const data = await crypto.subtle.encrypt({ name: "AES-GCM", iv }, await aesKey(hexKey), enc.encode(text));
  return `${toHex(iv)}:${toHex(data)}`;
}

async function decrypt(hexKey, payload) {
  const [ivHex, dataHex] = String(payload).split(":");
  try {
    const plain = await crypto.subtle.decrypt({ name: "AES-GCM", iv: fromHex(ivHex) }, await aesKey(hexKey), fromHex(dataHex));
    return new TextDecoder().decode(plain);
  } catch {
    throw new Error("Decryption failed"); // wrong key, or tampered: GCM's tag doesn't match
  }
}

The rest of this lesson

  • Encryption with a sealexplain
  • Why IVs must never repeatexplain
  • Same message twicepredict
  • Secret or public?match
  • AES-GCMwrite code
  • Badge quizquiz
  • What you builtrecap

Continue this lesson free — run real code in your browser

Continue with Google

See all 4 lessons of Project: A secure API gateway