ขนมปังตัวละครต้นฉบับประทับตราก้อนข้อมูลลงลิ้นชักแคช และมีตู้กุญแจแยกต่างหากสำหรับรหัสผ่าน

Bun.hash ทำ cache key ได้ไว แต่ไม่ใช่เกราะสำหรับรหัสผ่าน

พี่โชว์Engineering

เวลา key ยาวหรือเป็น binary การเก็บค่าเต็มลง index อาจไม่สะดวก Bun.hash ให้ non-cryptographic hash ที่เร็วสำหรับ hash table, cache partition หรือการเปรียบเทียบเบื้องต้น ค่าเริ่มต้นใช้ Wyhash และคืน bigint สำหรับผล 64 บิตครับ

คำว่าเร็วมีขอบเขตสำคัญ: hash แบบนี้ไม่ได้ออกแบบให้ต้านผู้โจมตีที่เลือก input เอง ไม่ควรใช้เก็บรหัสผ่าน สร้างลายเซ็น ตรวจความครบถ้วนจากแหล่งที่ไม่เชื่อถือ หรือแทน token แบบสุ่ม สำหรับรหัสผ่านให้ใช้ Bun.password; สำหรับ digest เชิงความปลอดภัยให้ใช้ Web Crypto หรือ node:crypto ตามสัญญาของระบบ

const encoder = new TextEncoder();

function cacheKey(namespace: string, payload: string): string {
  const bytes = encoder.encode(`${namespace}\0${payload}`);
  return Bun.hash(bytes).toString(16).padStart(16, "0");
}

const first = cacheKey("profile", "user-42");
const repeated = cacheKey("profile", "user-42");
const otherNamespace = cacheKey("avatar", "user-42");

if (first !== repeated) throw new Error("hash must be deterministic");
if (first === otherNamespace) throw new Error("namespace must affect the key");
console.log({ first, otherNamespace });

ออกแบบ cache ให้รับ collision

ผล hash มีพื้นที่จำกัด จึงมีโอกาสชนกันเสมอ แม้จะต่ำสำหรับข้อมูลทั่วไป อย่าใช้ hash เป็นหลักฐานว่าค่าสองก้อนเท่ากันโดยไม่ตรวจข้อมูลหรือ key ต้นฉบับเมื่อความถูกต้องสำคัญ รูปแบบที่ปลอดภัยกว่าคือใช้ hash หา bucket แล้วเปรียบเทียบ canonical input อีกครั้ง หรือเก็บ namespace/version คู่กับ digest

การต่อ string ตรง ๆ เช่น user + 42 อาจกำกวมกับ use + r42 ตัวอย่างจึงใส่ separator ที่ไม่อยู่ใน namespace และกำหนดลำดับ field ถ้า payload เป็น object ให้ canonicalize key order, encoding และ version ก่อน hash ไม่เช่นนั้น object เดียวกันอาจได้ cache key ต่างกันเพราะ serialization ต่างกัน

สุดท้ายอย่าบันทึก payload ลับเพื่อแก้ collision และอย่าคิดว่าการ hash เท่ากับการทำ anonymization ค่าโดเมนเล็ก เช่นอีเมลหรือเลขสมาชิก สามารถเดาและ hash เทียบได้ หาก key ต้องออกนอก trust boundary ให้ทบทวน threat model และใช้ keyed cryptographic construction ที่เหมาะสม

Recap

  • ใช้ Bun.hash กับ routing/cache ภายในที่รับ collision ได้
  • ใส่ namespace, separator และ schema version ให้ชัด
  • ตรวจ canonical input เมื่อความเท่ากันมีผลต่อความถูกต้อง
  • ใช้ password hash หรือ cryptographic digest เมื่อมี adversary ครับ