ฟังก์ชันสร้างกุญแจ: PBKDF2, bcrypt และ Argon2
เปรียบเทียบอัลกอริทึมแฮชรหัสผ่านตามความทนทานต่อการโจมตีด้วย GPU และ ASIC พร้อมทำความเข้าใจวิธีปรับปัจจัยงานและความยากด้านหน่วยความจำ
ฟังก์ชันสร้างกุญแจ: PBKDF2, bcrypt และ Argon2 เป็นบทเรียน Security+ Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Security+ Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Security+ Academy มีบทเรียนทั้งหมด 4 บทเรียน
เหตุใดการแฮชรหัสผ่านจึงแตกต่างกัน
การจัดเก็บรหัสผ่านต้องใช้ฟังก์ชันเข้ารหัสชนิดพิเศษที่เรียกว่า ฟังก์ชันแฮชรหัสผ่าน (PHF) หรือฟังก์ชันสร้างคีย์ (KDF) แฮชเข้ารหัสทั่วไปอย่าง SHA-256 ได้รับการออกแบบให้ทำงานรวดเร็ว โดย GPU รุ่นใหม่สามารถคำนวณแฮช SHA-256 ได้หลายพันล้านรายการต่อวินาที ความเร็วนี้เป็นภัยร้ายแรงต่อการจัดเก็บรหัสผ่าน เพราะผู้โจมตีที่ขโมยฐานข้อมูลแฮชไปได้สามารถลองรหัสผ่านจำนวนหลายพันล้านครั้งต่อวินาที KDF สำหรับรหัสผ่านจึงถูกทำให้ช้าโดยเจตนา และสามารถปรับค่าได้ เพื่อทำให้การโจมตีแบบลองครบทุกความเป็นไปได้ใช้ทรัพยากรจนไม่คุ้มค่า ขณะเดียวกันก็ยังอนุญาตให้การเข้าสู่ระบบที่ถูกต้องเสร็จภายในไม่กี่มิลลิวินาที
การเติมเกลือ: เอาชนะตารางเรนโบว์
ก่อนจะมี KDF สำหรับรหัสผ่านโดยเฉพาะ ผู้โจมตีใช้ตารางเรนโบว์ ซึ่งเป็นการจับคู่ค่าจากแฮชที่คำนวณไว้ล่วงหน้ากลับไปยังรหัสผ่านต้นฉบับ ค่าเกลือคือค่าสุ่มที่ไม่ซ้ำกันสำหรับผู้ใช้แต่ละคน โดยนำไปเติมไว้หน้าหรือหลังรหัสผ่านก่อนแฮช ทำให้แฮชทุกค่ามีเอกลักษณ์ แม้รหัสผ่านจะเหมือนกันก็ตาม ค่าเกลือจะถูกจัดเก็บไว้คู่กับแฮชในฐานข้อมูล ไม่จำเป็นต้องเก็บเป็นความลับ เพียงต้องเป็นค่าสุ่มเท่านั้น ค่าเกลือที่เหมาะสมต้องมีขนาดอย่างน้อย 16 ไบต์ สร้างโดยตัวสร้างเลขสุ่มที่ปลอดภัยทางการเข้ารหัส และจัดเก็บแยกสำหรับผู้ใช้แต่ละคน (ห้ามใช้ซ้ำข้ามบัญชี)
PBKDF2: มาตรฐานสำหรับรหัสผ่าน
PBKDF2 (ฟังก์ชันสร้างคีย์ตามรหัสผ่าน 2) กำหนดไว้ใน RFC 8018 และได้รับการรับรองโดย NIST หลักการทำงานคือใช้ฟังก์ชัน HMAC (โดยทั่วไปคือ HMAC-SHA-256) กับรหัสผ่านและค่าเกลือซ้ำหลายครั้ง ตามจำนวนรอบการทำซ้ำที่กำหนดได้ จำนวนรอบการทำซ้ำคือตัวกำหนดภาระงาน โดย NIST แนะนำให้ใช้ 600,000 รอบการทำซ้ำของ PBKDF2-HMAC-SHA256 เป็นอย่างน้อย ณ ปี 2023 PBKDF2 ถูกใช้อย่างแพร่หลาย (Django, พวงกุญแจ iOS, WPA2-PSK) แต่มีจุดอ่อนประการหนึ่งคือสามารถนำไปใช้งานบน GPU ได้อย่างมีประสิทธิภาพ จึงต้านทาน GPU ได้น้อยกว่าทางเลือกอื่น
# PBKDF2 example (Python pseudocode concept)
# import hashlib
# dk = hashlib.pbkdf2_hmac(
# 'sha256', # hash algorithm
# b'password', # password bytes
# b'random_salt', # salt bytes
# 600000 # iterations
# )bcrypt: ความยากด้านหน่วยความจำและ CPU
bcrypt ได้รับการออกแบบโดย Niels Provos และ David Mazieres ในปี 1999 และยังคงมีการใช้งานอย่างแพร่หลาย นวัตกรรมสำคัญคือปัจจัยต้นทุน (พารามิเตอร์จำนวนรอบ) โดยการเพิ่มค่าแต่ละครั้งจะทำให้เวลาคำนวณเพิ่มขึ้นเป็นสองเท่า bcrypt ใช้รหัสลับ Blowfish ที่ดัดแปลง พร้อมการตั้งค่าคีย์ Eksblowfishซึ่งใช้ทั้ง CPU และหน่วยความจำมาก ทำให้เร่งความเร็วบน GPU ได้ยากกว่า PBKDF2 อย่างมาก bcrypt ยังจำกัดข้อมูลรหัสผ่านไว้ที่ 72 ไบต์ (รหัสผ่านที่ยาวกว่านี้จะถูกตัด) ดังนั้นในบางการนำไปใช้จึงต้องแฮชรหัสผ่านที่ยาวก่อนด้วย SHA-256
# bcrypt cost factor
# Cost 10 = ~100ms on modern hardware
# Cost 12 = ~400ms
# Cost 14 = ~1600ms
# Each +1 doubles the work
# Recommended: cost 12-14 for web apps
# Command: htpasswd -bnBC 12 username passwordArgon2: ตัวเลือกสมัยใหม่ที่เหนือกว่า
Argon2 ชนะการแข่งขัน Password Hashing Competition ในปี 2015 และเป็นคำแนะนำปัจจุบันของ OWASP โดยมีสามรูปแบบ: Argon2d (เร็วกว่า แต่เสี่ยงต่อช่องทางด้านข้าง เหมาะที่สุดสำหรับสกุลเงินดิจิทัล), Argon2i (ใช้เวลาคงที่ เหมาะที่สุดสำหรับการแฮชรหัสผ่าน) และ Argon2id (แบบผสม ซึ่งแนะนำสำหรับการใช้งานส่วนใหญ่) Argon2id สามารถกำหนดค่าได้สามด้าน ได้แก่ ต้นทุนด้านเวลา (จำนวนรอบการทำซ้ำ) ต้นทุนด้านหน่วยความจำ (RAM ที่ต้องใช้) และการทำงานแบบขนาน (จำนวนเธรด) ความต้องการหน่วยความจำสูงทำให้การทำงานแบบขนานบน GPU ทำได้ยากมาก และแทบเป็นไปไม่ได้บน ASIC
# Argon2id recommended parameters (OWASP 2023)
# Memory: 64MB (65536 KiB)
# Iterations: 3
# Parallelism: 4 threads
# Output length: 32 bytes
# argon2 -id -t 3 -m 16 -p 4 -l 32ความยากด้านหน่วยความจำ: เหตุใดจึงเอาชนะการโจมตีด้วย GPU ได้
GPU มีแกนประมวลผลหลายพันแกน แต่มีหน่วยความจำต่อแกนจำกัด จึงเหมาะอย่างยิ่งกับการคำนวณง่าย ๆ ที่ใช้หน่วยความจำน้อย ฟังก์ชันที่มีความยากด้านหน่วยความจำ เช่น Argon2 และ scrypt ต้องใช้ RAM ปริมาณมากในการคำนวณแฮชแต่ละครั้ง หากผู้โจมตีต้องการเรียกใช้การคำนวณ Argon2id แบบขนาน 10,000 ครั้ง โดยแต่ละครั้งต้องใช้หน่วยความจำ 64MB ก็จะต้องใช้หน่วยความจำ GPU 640GB ซึ่งมากเกินกว่าที่คลัสเตอร์ GPU ใด ๆ จะมีได้ คุณสมบัตินี้เรียกว่าความยากด้านหน่วยความจำ และบังคับให้ผู้โจมตีต้องใช้การคำนวณแบบลำดับที่ช้า หรือลงทุนกับฮาร์ดแวร์ราคาแพงอย่างยิ่งจนการโจมตีไม่คุ้มค่า
การปรับค่าภาระงานในการใช้งานจริง
ภาระงานที่เหมาะสมขึ้นอยู่กับฮาร์ดแวร์และความหน่วงที่ยอมรับได้ เป้าหมายทั่วไปคือใช้เวลา 100-300 มิลลิวินาทีบนฮาร์ดแวร์สำหรับใช้งานจริงของเซิร์ฟเวอร์ต่อการยืนยันตัวตนหนึ่งครั้ง เมื่อฮาร์ดแวร์มีประสิทธิภาพดีขึ้น คุณควรเพิ่มภาระงาน นี่คือเหตุผลที่ bcrypt และ Argon2 จัดเก็บพารามิเตอร์ไว้คู่กับแฮช ทำให้สามารถอัปเกรดได้โดยไม่รบกวนผู้ใช้ โดยเมื่อเข้าสู่ระบบครั้งถัดไป ให้ตรวจสอบรหัสผ่านแล้วแฮชใหม่ด้วยพารามิเตอร์ที่สูงขึ้น OWASP จะปรับปรุงค่าขั้นต่ำที่แนะนำในปัจจุบันสำหรับ PBKDF2, bcrypt และ Argon2id ซึ่งควรทบทวนทุกปี
scrypt: KDF อีกแบบที่มีความยากด้านหน่วยความจำ
scrypt ออกแบบโดย Colin Percival ในปี 2009 เป็น KDF แบบมีความยากด้านหน่วยความจำตัวแรกที่ได้รับการใช้งานอย่างแพร่หลาย และใช้โดย Litecoin รวมถึงโปรแกรมจัดการรหัสผ่านจำนวนมาก scrypt กำหนดพารามิเตอร์ด้วย N (ต้นทุนด้าน CPU/หน่วยความจำ), r (ขนาดบล็อก) และ p (ปัจจัยการประมวลผลแบบขนาน) เช่นเดียวกับ Argon2 ค่า N ที่สูงต้องใช้ RAM ปริมาณมากในการคำนวณแต่ละครั้ง scrypt ถือว่าปลอดภัย แต่โดยทั่วไปแนะนำให้ใช้ Argon2id มากกว่าสำหรับแอปพลิเคชันใหม่ เพราะชนะ PHC และผ่านการวิเคราะห์ด้านการเข้ารหัสมากกว่า ทั้งสองแบบเป็นตัวเลือกที่ยอมรับได้
สิ่งที่ห้ามใช้: MD5, SHA-1 และ SHA ที่ไม่เติมเกลือ
แนวทางการแฮชหลายแบบต้องห้ามใช้กับรหัสผ่านโดยเด็ดขาด ได้แก่ MD5 (ถูกทำลายแล้ว และฮาร์ดแวร์สำหรับผู้บริโภคสามารถคำนวณได้หลายพันล้านแฮชต่อวินาที), SHA-1 (มีปัญหาเดียวกัน), SHA-256 ที่ไม่เติมเกลือ (ทำงานเร็วและตารางเรนโบว์สร้างได้ง่าย) และการเข้ารหัสแบบธรรมดา (ถอดกลับได้ การขโมยคีย์จึงเท่ากับได้รหัสผ่านทั้งหมด) เหตุการณ์ข้อมูลรั่วไหลในอดีตอย่างLinkedIn (2012) ใช้ SHA-1 ที่ไม่เติมเกลือ ทำให้รหัสผ่าน 117 ล้านรายการถูกเปิดเผยและถอดได้ภายในไม่กี่วัน ส่วนAdobe (2013) เข้ารหัสรหัสผ่านแทนการแฮช ซึ่งเป็นความเข้าใจผิดพื้นฐานและทำให้บัญชี 153 ล้านบัญชีถูกเปิดเผย เหตุการณ์เหล่านี้อยู่ในขอบเขตเนื้อหาสอบ Security+
การสร้างคีย์สำหรับคีย์เข้ารหัส
KDF ยังใช้สร้างคีย์เข้ารหัสจากรหัสผ่านได้ด้วย (ต่างจากการจัดเก็บแฮชของรหัสผ่าน) เมื่อผู้ใช้ตั้งรหัสผ่านหลักสำหรับคลังข้อมูลที่เข้ารหัส แอปพลิเคชันจะใช้ KDF เพื่อสร้างคีย์เข้ารหัส AES-256 ที่แท้จริงจากรหัสผ่านนั้น นี่คือเหตุผลที่โปรแกรมจัดการรหัสผ่านสามารถถอดรหัสคลังข้อมูลของคุณในอุปกรณ์ได้ โดยเรียกใช้ KDF กับรหัสผ่านหลักเพื่อสร้างคีย์เข้ารหัสขึ้นใหม่ และคีย์นี้จะไม่ออกจากอุปกรณ์ของคุณ HKDF (ฟังก์ชันสร้างคีย์จาก HMAC)เป็นมาตรฐานสำหรับสร้างหลายคีย์จากข้อมูลลับที่มีเอนโทรปีสูงค่าเดียว โดยใช้ใน TLS 1.3 เพื่อสร้างคีย์จับมือและคีย์แอปพลิเคชัน
การโจมตีด้วยการยัดข้อมูลประจำตัวและการป้องกันด้วย KDF
การโจมตีด้วยการยัดข้อมูลประจำตัว (Credential stuffing) คือการนำคู่ชื่อผู้ใช้และรหัสผ่านที่ขโมยมาจากการรั่วไหลครั้งหนึ่ง ไปทดลองใช้กับบริการอื่น ๆ การใช้ KDF ที่มีความแข็งแกร่งช่วยลดช่วงเวลาที่ผู้โจมตีมีสำหรับการถอดรหัสแบบออฟไลน์หลังเกิดการรั่วไหล — หากผู้โจมตีต้องใช้เวลา 300 มิลลิวินาทีต่อการคาดเดาหนึ่งครั้ง แทนที่จะใช้เวลาเพียงระดับไมโครวินาที การถอดรหัสรหัสผ่านแบบสุ่มความยาว 10 อักขระก็จะทำได้ยากเกินความเป็นไปได้ในทางคำนวณ อย่างไรก็ตาม KDF ไม่ได้ป้องกันการใช้รหัสผ่านซ้ำในหลายเว็บไซต์ — กรณีนี้ผู้ใช้ต้องใช้รหัสผ่านที่ไม่ซ้ำกัน การใช้ รหัสผ่านที่ไม่ซ้ำกัน + การจัดเก็บด้วย Argon2id + MFA ร่วมกัน ทำให้การโจมตีที่อาศัยข้อมูลประจำตัวแทบไม่ได้ผลในทางปฏิบัติ
ตรวจสอบความเข้าใจอย่างรวดเร็ว
ทดสอบความเข้าใจแนวคิด CompTIA Security+ (SY0-701) จากบทเรียนนี้
สรุปบทเรียน
ในบทเรียนนี้ คุณได้เรียนรู้ว่า KDF สำหรับรหัสผ่านถูกออกแบบให้ทำงานช้าโดยตั้งใจ และมีปัจจัยภาระงานที่ปรับได้ เพื่อทำให้การโจมตีแบบเดาสุ่มอย่างหนักหน่วงแบบออฟไลน์ทำได้ยากเกินความเป็นไปได้ในทางคำนวณ, ฟังก์ชันที่ต้องใช้หน่วยความจำสูง เช่น Argon2id และ scrypt สามารถต้านการประมวลผลแบบขนานด้วย GPU ได้ด้วยการกำหนดให้การคำนวณแต่ละครั้งต้องใช้ RAM ปริมาณมาก และ MD5, SHA-1 และแฮชที่ไม่ใส่ค่าเกลือไม่เหมาะสมอย่างสิ้นเชิง สำหรับการจัดเก็บรหัสผ่าน ดังที่แสดงให้เห็นจากเหตุการณ์ข้อมูลรั่วไหลครั้งใหญ่หลายครั้ง ต่อไปเราจะศึกษาเรื่องการเข้ารหัสหลังยุคควอนตัมและอัลกอริทึมที่ NIST เลือกเพื่อทดแทน RSA และ ECC
คำถามที่พบบ่อย
บทเรียน “ฟังก์ชันสร้างกุญแจ: PBKDF2, bcrypt และ Argon2” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “ฟังก์ชันสร้างกุญแจ: PBKDF2, bcrypt และ Argon2” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Security+ Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Security+ Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “ฟังก์ชันสร้างกุญแจ: PBKDF2, bcrypt และ Argon2”
เปรียบเทียบอัลกอริทึมแฮชรหัสผ่านตามความทนทานต่อการโจมตีด้วย GPU และ ASIC พร้อมทำความเข้าใจวิธีปรับปัจจัยงานและความยากด้านหน่วยความจำ คุณปฏิบัติ Security+ Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Security+ Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Security+ Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “ฟังก์ชันสร้างกุญแจ: PBKDF2, bcrypt และ Argon2” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Security+ Academy นี้ได้ไหม
ได้ บทเรียน Security+ Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การจับมือ TLS 1.3 และการกลับมาใช้เซสชัน 0-RTT
- การเข้ารหัสที่ยืนยันตัวตน: AES-GCM และ ChaCha20-Poly1305
- ฟังก์ชันสร้างกุญแจ: PBKDF2, bcrypt และ Argon2
- การเข้ารหัสหลังยุคควอนตัม: CRYSTALS-Kyber และ Dilithium