

ระบบล็อกอินต้องรู้ว่ารหัสที่ผู้ใช้กรอกตรงกับที่ตั้งไว้หรือไม่ แต่โดยทั่วไปไม่ได้จำเป็นต้องอ่านรหัสเดิมกลับมาแสดง การออกแบบที่เก็บจึงเริ่มจากหน้าที่ตรวจความถูกต้อง มากกว่าหาวิธีซ่อนข้อความแล้วถอดคืนเมื่อถึงเวลา
Hashing สำหรับ password กับการเข้ารหัสที่ถอดกลับได้ตอบคนละโจทย์ และการใช้คำว่า hash ก็ยังไม่พอ เพราะฟังก์ชันที่เหมาะกับ checksum ของไฟล์ไม่ได้ถูกออกแบบให้เพิ่มต้นทุนการเดารหัสแบบเดียวกัน
ควรแยกความต้องการของข้อมูลก่อนครับ แล้วเลือกกลไกที่ library หรือ framework รองรับ พร้อมคิดถึงการตรวจ การอัปเกรดและการกู้บัญชีในภายหลัง
การเข้ารหัสแบบกลับได้อาศัยกุญแจเพื่ออ่านข้อความเดิม เหมาะกับข้อมูลที่ระบบจำเป็นต้องอ่านคืนตามหน้าที่ แต่ถ้านำมาเก็บ password สำหรับล็อกอินของบริการเอง กุญแจนั้นก็กลายเป็นทางที่ทำให้รหัสจำนวนมากถูกอ่านกลับได้เมื่อเข้าถึงครบชุด
Password hashing สร้างข้อมูลสำหรับใช้ตรวจ โดยไม่มีขั้นถอด hash กลับเป็น password ตามหน้าที่ของมัน เมื่อผู้ใช้กรอก ระบบใช้ฟังก์ชัน verify ของกลไกนั้นกับค่าที่เก็บไว้ ไม่ใช้การอ่านรหัสเดิมออกมาเทียบตรงๆ
อย่างไรก็ตาม คำว่าถอดกลับไม่ได้ไม่ได้แปลว่าเดาไม่ได้ ผู้ที่ได้ข้อมูล hash อาจลองรหัสที่คาดว่าเป็นไปได้ผ่านอัลกอริทึมแล้วเทียบผล จึงต้องมีทั้งต้นทุนการลองที่เหมาะสมและการดูแลไม่ให้ข้อมูลรับรองหลุด ไม่อ้างว่า hash ทำให้รหัสสั้นที่เดาง่ายปลอดภัยเสมอ
การรีเซ็ตรหัสจึงต่างจากการส่งรหัสเดิมคืนให้ผู้ใช้ หากระบบต้องมีปุ่มอ่าน password เดิมสำหรับบัญชีของตัวเอง ควรกลับไปทบทวนว่าความต้องการนั้นจำเป็นจริงหรือเป็นผลจากกระบวนการช่วยเหลือที่ยังออกแบบไม่ครบ

Salt เป็นข้อมูลเฉพาะที่ใช้ร่วมกับ password hashing เพื่อให้รหัสเหมือนกันของคนละรายการไม่กลายเป็นผลชุดเดียวกันตามการใช้งานที่ถูกต้อง และช่วยลดประโยชน์ของตารางคำนวณล่วงหน้าที่ใช้เทียบหลายบัญชีพร้อมกัน
Salt ไม่ได้มีบทบาทเป็นความลับแบบกุญแจถอดรหัส จึงเก็บร่วมกับข้อมูล hash และพารามิเตอร์ตามรูปแบบที่ library กำหนดได้ การแยก salt ไปอีกตารางไม่ได้แทนการใช้ password hashing ที่ถูกต้อง
Library ระดับสูงจำนวนมากสร้างและจัดการ salt ให้เมื่อใช้อย่างถูกวิธี ควรอ่าน API ว่าต้องส่งอะไรและคืนรูปแบบใด ไม่สุ่มเองแล้วต่อ string แบบที่คิดขึ้น หรือใช้ค่าชื่อผู้ใช้ซ้ำๆ แทนกลไกที่เอกสารรองรับ
รูปแบบที่เก็บอาจมีตัวระบุอัลกอริทึม พารามิเตอร์ salt และผลตรวจอยู่ด้วยกัน เราจึงควรมองทั้งชุดเป็น credential record ที่มีรุ่น ไม่เลือกคัดเฉพาะส่วนท้ายที่ดูเหมือน hash แล้วทำข้อมูลที่ต้องใช้ verify หายไป
ฟังก์ชัน hash ที่เร็วเหมาะกับงานตรวจความสมบูรณ์หลายชนิด แต่ความเร็วไม่ใช่เป้าหมายเดียวของการเก็บ password แนวทางอย่าง Argon2id ออกแบบให้มีต้นทุนด้านทรัพยากรที่ปรับได้ตามพารามิเตอร์ เพื่อทำให้การลองรหัสจำนวนมากมีภาระมากขึ้น
ต้องเลือกจากคำแนะนำของอัลกอริทึมกับ implementation ที่ดูแลอยู่ และทดสอบในบริบทของบริการ ไม่ยกค่าที่ใช้เวลาเหมาะบนเครื่องหนึ่งไปเป็นผลของทุก deployment โดยยังไม่ดูจำนวนคำขอที่เกิดพร้อมกัน
การตั้งต้นทุนสูงขึ้นมีภาระต่อฝั่งตรวจรหัสด้วย หากไม่เผื่อหน่วยความจำและความพร้อมรับงานพร้อมกัน ระบบอาจติดขัดเมื่อมีคำขอมาก จึงควรออกแบบการจำกัดความพยายามและงบทรัพยากรร่วมกัน ไม่ลดต้นทุนให้ต่ำเพื่อให้การโจมตีเดารหัสไม่ทำให้ server ช้าเพียงด้านเดียว
บทบาทของการวัดคือหาว่าพารามิเตอร์ที่ผ่านข้อกำหนดทำงานภายใต้งบของบริการได้อย่างไร ไม่ใช่เลือกสิ่งที่เร็วที่สุดแล้วเรียกว่าดีที่สุด ควรเก็บวิธีตรวจ รุ่นเครื่องมือและผลจริงก่อนอ้างระยะเวลาหรือความสามารถรองรับคำขอ

Pepper เป็นข้อมูลลับเพิ่มเติมในบางกลยุทธ์ ซึ่งมีบทบาทต่างจาก salt และควรเก็บแยกจากฐานข้อมูล password ตามแนวทางที่ใช้ หากผู้เข้าถึงฐานได้อย่างเดียว ยังไม่ได้ส่วนลับนั้น ก็เพิ่มการป้องกันตามขอบเขตของกลยุทธ์
แต่การมี pepper ไม่ใช่เหตุให้เลือก hash ที่ไม่เหมาะหรือเก็บ password แบบเดาได้ง่าย และไม่ได้แก้ความเสี่ยงหากตัวแอปที่ถือความลับถูกควบคุมพร้อมกัน ต้องอธิบายด้วยว่ากำลังเพิ่มขอบเขตป้องกันแบบใด
ก่อนนำมาใช้ต้องคิดถึงการหมุนค่า การกู้เมื่อระบบเก็บความลับไม่พร้อม และกรณี pepper เดิมรั่ว เพราะบางวิธีเปลี่ยนค่าที่คุ้มครองข้อมูลเก่าไม่ได้โดยไม่รู้ password ผู้ใช้ อาจต้องมีการ verify แล้วอัปเกรดหรือกระบวนการ reset ตามแผน ไม่คิดเพียงขั้นเพิ่มความลับตอนสมัครครั้งแรก
ระบบที่เก็บรุ่นอัลกอริทึมกับพารามิเตอร์ไว้สามารถรู้ได้ว่ารายการใดใช้กติกาเก่า เมื่อผู้ใช้ล็อกอินและ verify ผ่าน จึงมีโอกาสนำรหัสที่เพิ่งรับมาตรวจแล้วไปสร้าง record ใหม่ตามนโยบายที่อัปเกรด
ต้องจัดการการเขียนอย่างระมัดระวังและไม่ทิ้งค่าก่อนหน้าเพียงเพราะเริ่มกระบวนการใหม่แล้ว หากสร้างหรือเก็บ record ใหม่ไม่ผ่าน ต้องมีสถานะที่ไม่ทำให้บัญชีใช้ไม่ได้โดยไม่มีทางตรวจต่อ ทั้งยังไม่เก็บ plaintext ไว้รอ batch ย้ายภายหลัง
สำหรับผู้ใช้ที่ไม่กลับมาล็อกอิน อาจต้องมีนโยบายหมดอายุข้อมูลเก่าหรือ reset ตามความเสี่ยงของระบบ การมีโค้ด rehash ตอนล็อกอินไม่ได้เปลี่ยนทุกบัญชีเก่าทันที จึงต้องติดตามยอดค้างตามรุ่นโดยไม่เปิดเผยค่า credential
ชุดตรวจควรครอบคลุมรหัสถูกผิด รูปแบบ record เก่า การอัปเกรดที่เขียนไม่ผ่าน และข้อความ error ที่ไม่เผยรายละเอียดภายใน ใช้บัญชีทดลองกับฟังก์ชันของ library ไม่เขียนตัวตรวจ crypto เองเพื่อให้ตัวอย่างสั้นหรือพิมพ์ password ลง log ระหว่างทดสอบ
การเก็บ password ที่ใช้ยืนยันบัญชีเริ่มจากการตรวจโดยไม่ต้องมีทางอ่านรหัสเดิมคืน Salt ต้นทุนของ password hashing และ pepper มีหน้าที่ต่างกัน เมื่อใช้กลไกที่ดูแลอยู่พร้อม record ที่มีรุ่นกับแผนอัปเกรด เราจะรักษาการตรวจให้ทำต่อได้ตามอายุระบบ โดยไม่สับสนว่าการซ่อนข้อมูลหรือใช้ hash ชื่อใดชื่อหนึ่งรับรองความปลอดภัยครบแล้ว