• auth
  • password
  • security
  • hashing
  • bcrypt
  • argon2
  • sha1
  • sha2
  • login
  • sign-in

วิวัฒนาการของการแฮชรหัสผ่าน

คุณอาจเคยได้ยินคำแนะนำในการเลือกอัลกอริธึมแฮชรหัสผ่าน แต่คุณเคยคิดไหมว่าทำไมถึงแนะนำสิ่งเหล่านี้? ในบทความนี้ เราจะสำรวจวิวัฒนาการของอัลกอริธึมแฮชรหัสผ่านและเหตุผลเบื้องหลังพวกมัน

Gao
Gao
Founder

บทนำ

การแฮชรหัสผ่าน ตามชื่อเลย คือกระบวนการของการคำนวณค่าแฮชจากรหัสผ่าน ค่าของแฮชมักถูกเก็บในฐานข้อมูล และในกระบวนการเข้าสู่ระบบ (sign-in) ค่าแฮชของรหัสผ่านที่ผู้ใช้ป้อนเข้ามาจะถูกคำนวณและเปรียบเทียบกับค่าแฮชที่เก็บไว้ในฐานข้อมูล หากตรงกัน ผู้ใช้จะได้รับการยืนยันตัวตน

ก่อนที่เราจะลงลึกในวิวัฒนาการของอัลกอริธึมแฮชรหัสผ่าน สิ่งสำคัญคือการเข้าใจว่าทำไมมันถึงจำเป็น

รหัสผ่านแบบข้อความธรรมดา: ความเสี่ยงด้านความปลอดภัยขนาดใหญ่

ลองนึกภาพว่าคุณเป็นผู้ใช้ของเว็บไซต์ที่คุณลงทะเบียนบัญชีไว้ วันหนึ่งเว็บไซต์นั้นถูกแฮ็กและฐานข้อมูลถูกทำให้รั่วไหล หากเว็บไซต์นั้นเก็บรหัสผ่านในรูปแบบข้อความธรรมดา แฮกเกอร์สามารถเข้าถึงรหัสผ่านของคุณได้โดยตรง เนื่องจากหลายคนใช้รหัสผ่านซ้ำกันในหลายเว็บไซต์ แฮกเกอร์สามารถใช้รหัสผ่านนี้เพื่อเข้าถึงบัญชีอื่น ๆ ของคุณได้โดยไม่ได้รับอนุญาต สถานการณ์จะยิ่งรุนแรงขึ้นไปอีกหากคุณใช้รหัสผ่านเดียวกันหรือคล้ายกันกับบัญชีอีเมลของคุณ เพราะแฮกเกอร์สามารถรีเซ็ตรหัสผ่านของคุณและยึดครองบัญชีทั้งหมดที่เกี่ยวข้องได้

แม้ไม่มีข้อมูลรั่วไหล ในทีมขนาดใหญ่ก็มีใครบางคนที่มีการเข้าถึงฐานข้อมูลสามารถเห็นรหัสผ่านได้ เมื่อเทียบกับข้อมูลอื่น ๆ รหัสผ่านเป็นข้อมูลที่อ่อนไหวสูง และคุณคงไม่ต้องการให้ใครมีการเข้าถึงมันเลย

การเก็บรหัสผ่านโดยไม่แฮชถือเป็นข้อผิดพลาดของมือสมัครเล่น น่าเสียดาย หากคุณค้นหาคำว่า "รหัสผ่านรั่วไหลในรูปแบบข้อความธรรมดา" คุณจะพบว่าบริษัทใหญ่ ๆ เช่น Facebook, DailyQuiz และ GoDaddy ก็เคยประสบปัญหารหัสผ่านรั่วไหลในรูปแบบข้อความธรรมดา เป็นไปได้ว่าบริษัทอื่น ๆ อีกหลายแห่งก็ได้ทำข้อผิดพลาดเช่นนี้

การเข้ารหัส v.s. การขออนุญาต v.s. การแฮช

สามคำนี้มักถูกสับสน แต่แท้จริงแล้วพวกมันเป็นแนวคิดที่ต่างกัน

การเข้ารหัส

การเข้ารหัสคือสิ่งที่ต้องตัดออกไปก่อนสำหรับการเก็บรหัสผ่าน เช่น Base64 เป็นอัลกอริธึมการเข้ารหัสที่แปลงข้อมูลไบนารีให้เป็นสตริงของตัวอักษร:

การรู้จักอัลกอริธึมการเข้ารหัสทำให้ใครก็สามารถถอดรหัสสตริงที่เข้ารหัสและดึงข้อมูลต้นฉบับออกมาได้:

สำหรับแฮกเกอร์ ส่วนมากอัลกอริธึมเข้ารหัสเหมือนกับข้อความธรรมดา

การขออนุญาต

ก่อนการแฮชจะเป็นที่นิยม การขออนุญาตถูกใช้เพื่อเก็บรหัสผ่าน เช่น ด้วย AES การเข้ารหัสเกี่ยวข้องกับการใช้คีย์ (หรือคู่ของคีย์) เพื่อเข้ารหัสและถอดรหัสข้อมูล

ปัญหากับการขออนุญาตปรากฏชัดเจนในคำว่า "ถอดรหัส" การขออนุญาตสามารถดำเนินการย้อนกลับได้ หมายความว่าหากแฮกเกอร์ได้คีย์มา พวกเขาสามารถถอดรหัสรหัสผ่านและดึงรหัสผ่านในรูปแบบข้อความธรรมดาได้

การแฮช

ความแตกต่างหลัก ๆ ระหว่างการแฮช การเข้ารหัส และการขออนุญาตคือการแฮชเป็นสิ่งที่ไม่สามารถย้อนกลับได้ เมื่อรหัสผ่านถูกแฮชแล้ว มันไม่สามารถถูกถอดรหัสให้เป็นรูปแบบต้นฉบับได้อีก

ในฐานะเจ้าของเว็บไซต์ คุณไม่จำเป็นต้องรู้รหัสผ่านเอง ตราบเท่าที่ผู้ใช้สามารถเข้าสู่ระบบได้ด้วยรหัสผ่านที่ถูกต้อง กระบวนการลงทะเบียนสามารถสรุปได้ดังนี้:

  1. ผู้ใช้ป้อนรหัสผ่าน
  2. บริการใช้การแฮชอัลกอริธึมเพื่อคำนวณค่าของแฮชของรหัสผ่าน
  3. บริการเก็บค่าของแฮชในฐานข้อมูล

เมื่อผู้ใช้เข้าสู่ระบบ กระบวนการเป็นดังนี้:

  1. ผู้ใช้ป้อนรหัสผ่าน
  2. บริการใช้การแฮชอัลกอริธึมเดิมเพื่อคำนวณค่าของแฮชของรหัสผ่าน
  3. บริการเปรียบเทียบค่าของแฮชกับค่าของแฮชที่เก็บไว้ในฐานข้อมูล
  4. หากค่าของแฮชตรงกัน ผู้ใช้จะได้รับการยืนยันตัวตน

ทั้งสองกระบวนการนี้หลีกเลี่ยงการเก็บรหัสผ่านเป็นข้อความธรรมดา และเนื่องจากการแฮชไม่สามารถย้อนกลับได้ แม้ว่าฐานข้อมูลจะถูกแฮกเกอร์เจาะได้แค่ค่าของแฮชที่ดูเหมือนเป็นสตริงสุ่มเท่านั้น

ชุดเริ่มต้นของอัลกอริธึมแฮช

การแฮชอาจดูเหมือนเป็นวิธีแก้ปัญหาที่สมบูรณ์แบบสำหรับการเก็บรหัสผ่าน แต่มันไม่ง่ายแบบนั้น เพื่อเข้าใจว่าทำไม เรามาสำรวจวิวัฒนาการของอัลกอริธึมแฮชรหัสผ่านกันเถอะ

MD5

ในปี 1992 Ron Rivest ได้ออกแบบ อัลกอริธึม MD5 ซึ่งเป็นอัลกอริธึมสรุปข้อความที่สามารถคำนวณค่าแฮช 128 บิตจากข้อมูลใด ๆ MD5 ถูกใช้กันอย่างแพร่หลายในหลายสาขา รวมถึงการแฮชรหัสผ่านด้วย ตัวอย่างเช่น ค่าของแฮช MD5 ของ "123456" คือ:

อย่างที่กล่าวมาก่อนหน้านี้ ค่าของแฮชดูเหมือนเป็นสตริงสุ่มและไม่สามารถย้อนกลับได้ ยิ่งไปกว่านั้น MD5 มีความเร็วและง่ายต่อการทำให้มันกลายเป็นอัลกอริธึมแฮชรหัสผ่านที่นิยมมากที่สุด

อย่างไรก็ตาม ข้อได้เปรียบของ MD5 ก็คือข้อเสียเช่นกันในการแฮชรหัสผ่าน ความเร็วของมันทำให้มันเป็นเป้าหมายง่ายต่อการโจมตีด้วยวิธี brute-force หากแฮกเกอร์มีรายชื่อของรหัสผ่านที่พบบ่อยและข้อมูลส่วนตัวของคุณ พวกเขาสามารถคำนวณค่าของแฮช MD5 ของแต่ละส่วนประกอบและเปรียบเทียบกับค่าของแฮชในฐานข้อมูลได้ ตัวอย่างเช่นพวกเขาอาจรวมวันเกิดของคุณกับชื่อของคุณหรือกับชื่อสัตว์เลี้ยงของคุณ

ในปัจจุบัน เครื่องคอมพิวเตอร์มีพลังมากกว่าก่อน ทำให้มันง่ายต่อการโจมตี brute force แฮชรหัสผ่านของ MD5

ตระกูล SHA

ทำไมไม่ใช้อัลกอริธึมอื่นที่สร้างค่าของแฮชที่ยาวขึ้น? ตระกูล SHA ดูเหมือนจะเป็นทางเลือกที่ดี SHA-1 เป็นอัลกอริธึมแฮชที่สร้างค่าของแฮช 160 บิต และ SHA-2 เป็นตระกูลอัลกอริธึมแฮชที่สร้างค่าของแฮชที่มีความยาว 224 บิต, 256 บิต, 384 บิต, และ 512 บิต ลองดูค่าของแฮช SHA-256 ของ "123456":

ค่าของแฮช SHA-256 ยาวกว่าของ MD5 และมันก็ไม่สามารถย้อนกลับได้ แต่ยังมีปัญหาอีก หากคุณรู้จักค่าของแฮชแล้ว อย่างที่เห็นในข้างบน และคุณเห็นค่าของแฮชที่แน่ชัดในฐานข้อมูล คุณจะรู้เลยว่ารหัสผ่านคือ "123456" แฮกเกอร์สามารถสร้างรายชื่อของรหัสผ่านที่พบบ่อยและค่าของแฮชที่ตรงกันและเปรียบเทียบกับค่าของแฮชในฐานข้อมูลได้ รายชื่อนี้เป็นที่รู้จักกันว่าเป็น rainbow table

Salt

เพื่อบรรเทาการโจมตีด้วย rainbow table แนวคิดของ salt ได้ถูกแนะนำ Salt เป็นสตริงสุ่มที่ถูกเพิ่มเข้าไปในรหัสผ่านก่อนการแฮช ตัวอย่างเช่น หาก salt คือ "salt" และคุณต้องการใช้ SHA-256 เพื่อแฮชรหัสผ่าน "123456" พร้อมกับ salt แทนที่จะทำง่าย ๆ แบบนี้:

คุณควรจะทำแบบนี้:

อย่างที่เห็น ผลลัพธ์จะแตกต่างไปจากการแฮชโดยไม่มี salt โดยทั่วไปแล้ว ผู้ใช้แต่ละคนจะได้รับ salt แบบสุ่มระหว่างการลงทะเบียนซึ่งถูกเก็บในฐานข้อมูลข้างค่าของแฮช ในกระบวนการเข้าสู่ระบบ salt ถูกใช้ในการคำนวณค่าของแฮชของรหัสผ่านที่ป้อนเข้ามาและเปรียบเทียบกับค่าของแฮชที่เก็บไว้

Iteration

ถึงแม้จะเพิ่ม salt ค่าของแฮชยังคงไวต่อการโจมตีด้วยวิธี brute-force เนื่องจากฮาร์ดแวร์มีประสิทธิภาพมากขึ้น เพื่อทำให้ยากขึ้น Iteration (เช่น การรันอัลกอริธึมแฮชหลายครั้ง) สามารถถูกนำมาใช้ได้ ตัวอย่างเช่นแทนที่จะใช้:

คุณสามารถใช้:

การเพิ่มจำนวน iteration ทำให้การโจมตีด้วยวิธี brute-force ยากขึ้น แต่สิ่งนี้ก็จะกระทบกระบวนการเข้าสู่ระบบเพราะมันจะทำให้ช้าลง ดังนั้น จำเป็นต้องหาสมดุลระหว่างความปลอดภัยและประสิทธิภาพ

ช่วงพักกลาง

มาพักกันหน่อยและสรุปลักษณะของอัลกอริธึมแฮชรหัสผ่านที่ดี:

  • ไม่สามารถย้อนกลับได้ (preimage resistance)
  • ยากต่อการโจมตีด้วยวิธี brute-force
  • ทนทานต่อการโจมตีด้วย rainbow table

อย่างที่คุณอาจสังเกตเห็น salt และ iteration จำเป็นเพื่อทำตามข้อกำหนดทั้งหมดนี้ ปัญหาคือทั้ง MD5 และตระกูล SHA ไม่ได้ถูกออกแบบมาเฉพาะสำหรับการแฮชรหัสผ่าน; พวกมันถูกใช้กันทั่วไปในการตรวจสอบความสมบูรณ์ (หรือ "สรุปข้อความ") ด้วยเหตุนี้ แต่ละเว็บไซต์อาจมีการใช้งาน salt และ iteration แตกต่างกัน ทำให้เกิดความท้าทายในการมาตรฐานและการย้ายข้อมูล

อัลกอริธึมแฮชรหัสผ่าน

เพื่อแก้ปัญหานี้ มีหลายอัลกอริธึมแฮชที่ถูกออกแบบมาเฉพาะสำหรับการแฮชรหัสผ่าน ลองมาดูกันบ้าง

bcrypt

bcrypt เป็นอัลกอริธึมแฮชรหัสผ่านที่ถูกออกแบบโดย Niels Provos และ David Mazières มันถูกใช้กันอย่างแพร่หลายในหลายภาษาโปรแกรม นี่คือตัวอย่างของค่าแฮช bcrypt:

แม้ว่ามันจะดูเหมือนเป็นสตริงสุ่มอีกอัน แต่มันมีข้อมูลเพิ่มเติม ลองแยกดู:

  • ส่วนแรก $2y บ่งบอกถึงอัลกอริธึมซึ่งคือ 2y.
  • ส่วนที่สอง $12 บ่งบอกจำนวน iteration ซึ่งคือ 12 ซึ่งหมายความว่าอัลกอริธึมแฮชจะถูกรัน 212=4096 ครั้ง (iteration).
  • ส่วนที่สาม wNt7lt/xf8wRJgPU7kK2ju คือ salt.
  • ส่วนสุดท้าย GrirhHK4gdb0NiCRdsSoAxqQoNbiluu คือค่าของแฮช.

bcrypt มีบางข้อจำกัด:

  • ความยาวสูงสุดของรหัสผ่านคือ 72 byte.
  • salt ถูกจำกัดที่ 16 byte.
  • ค่าของแฮชถูกจำกัดที่ 184 bit.

Argon2

เนื่องจากข้อถกเถียงและข้อจำกัดของอัลกอริธึมแฮชรหัสผ่านที่มีอยู่ การแข่งขันแฮชรหัสผ่าน password hashing competition ได้จัดขึ้นในปี 2015 โดยไม่ลงรายละเอียด ลองโฟกัสที่ผู้ชนะ: Argon2.

Argon2 เป็นอัลกอริธึมแฮชรหัสผ่านที่ออกแบบโดย Alex Biryukov, Daniel Dinu และ Dmitry Khovratovich มันนำเสนอแนวคิดใหม่บางข้อ:

  • Memory-hard: อัลกอริธึมถูกออกแบบมาให้ยากต่อการประมวลผลแบบคู่ขนาน ทำให้การโจมตีด้วย GPU ยากขึ้น
  • Time-hard: อัลกอริธึมถูกออกแบบมาให้ยากต่อการปรับแต่ง ทำให้การโจมตีด้วย ASIC (Application-specific integrated circuits) ยากขึ้น
  • Side-channel resistant: อัลกอริธึมถูกออกแบบมาให้ทนทานต่อการโจมตีช่องทางข้าง เช่น การโจมตีเวลา

มีสองเวอร์ชันหลักของ Argon2, Argon2i และ Argon2d. Argon2i ปลอดภัยที่สุดต่อการโจมตีช่องช่องข้าง ในขณะที่ Argon2d ให้ความต้านทานสูงสุดต่อการโจมตี GPU.

-- Argon2

นี่คือตัวอย่างของค่าแฮช Argon2:

ลองแยกดู:

  • ส่วนแรก $argon2i บ่งบอกถึงอัลกอริธึมซึ่งคือ argon2i.
  • ส่วนที่สอง $v=19 บ่งบอกถึงเวอร์ชันซึ่งคือ 19.
  • ส่วนที่สาม $m=16,t=2,p=1 บ่งบอกถึงค่าใช้จ่ายหน่วยความจำ ค่าใช้จ่ายเวลา และระดับการขนานซึ่งคือ 16, 2 และ 1.
  • ส่วนที่สี่ $YTZ5ZnpXRWN5SlpjMHBDRQ คือ salt.
  • ส่วนสุดท้าย $12oUmJ6xV5bIadzZHkuLTg คือค่าของแฮช.

ใน Argon2 ความยาวสูงสุดของรหัสผ่านคือ 232-1 byte, salt ถูกจำกัดที่ 232-1 byte และค่าของแฮชถูกจำกัดที่ 232-1 byte ซึ่งเพียงพอสำหรับสถานการณ์ส่วนใหญ่

Argon2 มีอยู่ในหลายภาษาโปรแกรมเช่น node-argon2 สำหรับ Node.js และ argon2-cffi สำหรับ Python

สรุป

ตลอดหลายปีที่ผ่านมา อัลกอริธึมแฮชรหัสผ่านได้ผ่านการวิวัฒนาการอย่างมีนัยสำคัญ เราต้องขอบคุณชุมชนความปลอดภัยสำหรับความพยายามหลายสิบปีในการทำให้อินเทอร์เน็ตเป็นที่ปลอดภัยขึ้น ขอบคุณการมีส่วนร่วมของพวกเขา นักพัฒนาสามารถให้ความสำคัญกับการสร้างบริการที่ดีขึ้นโดยไม่ต้องกังวลเกี่ยวกับความปลอดภัยของการแฮชรหัสผ่าน แม้ว่าการป้องกันความปลอดภัย 100% ในระบบอาจจะไม่สามารถทำได้ แต่เราสามารถใช้นโยบายหลากหลายเพื่อเสี่ยงต่อความเสี่ยงที่เกี่ยวข้อง

หากคุณต้องการหลีกเลี่ยงความยุ่งยากในการดำเนินการยืนยันและอำนาจอนุญาต ลองใช้ Logto ฟรี เรามีโซลูชันที่ปลอดภัย (เราใช้ Argon2!), เชื่อถือได้ และมีความสามารถขยายได้ ช่วยให้คุณสามารถมุ่งมั่นกับการสร้างผลิตภัณฑ์ของคุณได้