นโยบายและการจัดเก็บรหัสผ่านที่ควรจะเป็น

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

การรับอักขระของรหัสผ่าน

ข้อมูลต่อไปนี้เป็นคำแนะนำในขั้นตอนการตรวจสอบรับข้อมูลรหัสผ่านโดยที่ยังไม่ผ่านการ hash ใดๆก่อน เพื่อตรวจสอบให้เป็นไปตามเงื่อนไขความปลอดภัย.
คำว่ารับหรือไม่รับอักขระ หมายถึงตัวอักษรเป็นตัวๆ, คำว่ารับหรือไม่รับรหัสผ่าน หมายถึงตัวอักษรทั้งหมดที่กรอกผ่านฟอร์มรหัสผ่าน.

  • รหัสผ่านต้องมีความยาวมากกว่า 3 ตัวอักษร (จากคห.ของผู้เขียน - กรณีในขั้นตอนพัฒนาซอฟต์แวร์บนเครื่อง เพื่อความสะดวกไม่ต้องพิมพ์ยาวนัก).
  • รหัสผ่านควรมีความยาวตั้งแต่หรือมากกว่า 8 ตัวอักษรขึ้นไป (จากคห. ของผู้เขียน - อาจเปลี่ยนจากควรมีเป็นต้องมี คือ บังคับให้ยาวตั้งแต่ 8 ตัวอักษรขึ้นไป สำหรับระบบที่ต้องการความปลอดภัยสูง).
  • ไม่ควรจำกัดความยาวของอักขระ หรือจำกัดไม่เกิน 72 ไบต์สำหรับ bcrypt. ตัวอย่างเช่น อักขระภาษาไทยจะใช้ประมาณ 3 ไบต์ ถ้าจะรับทั้งหมด 10 ตัวจะใช้ประมาณ 30 ไบต์, อักขระ emoji จะใช้ 4 ไบต์ ถ้าใช้ผสมกันก็ต้องนับเผื่อจากมากที่สุดคือตัวละ 4 ไบต์ โดยทั้งหมด 72 ไบต์สำหรับ bcrypt จะได้ 18 ตัวอักษร. ทั้งนี้หากเก็บข้อมูลโดยใช้ hash รูปแบบอื่น ข้อจำกัดจะเปลี่ยนไป โดยจะเก็บได้มากขึ้น แต่โดยหลักการทั่วไปไม่ควรให้เกิน 100 ตัวอักษร เพราะจะเกินความจำเป็น.
  • ควรรับอักขระต่อไปนี้ โดยไม่จำเป็นต้องมีครบทุกเงื่อนไขก็ได้ (จากคห.ของผู้เขียน - เราควรสนับสนุนการตั้งรหัสผ่านอย่างเสรี และเน้นไปที่ความยาวมากกว่าที่จะไปบังคับให้ผู้ใช้ตั้งสิ่งที่จำได้ยาก จนกระทั่งสุดท้ายผลักเขาไปตั้งรหัสที่เหมือนจะจำยากแต่เดาง่ายแทน เช่น pA55w+rd).
    • ต้องรับอักขระภาษาอังกฤษ ตัวเล็กและตัวใหญ่มีความต่างกัน.
    • ต้องรับอักขระที่เป็นตัวเลข โดยจะมีตัวเดียวหรือมากกว่าก็ได้.
    • ต้องรับอักขระที่เป็นตัวอักษรพิเศษ โดยจะมีตัวเดียวหรือมากกว่าก็ได้ เช่น ( ) ' " ! @ # $ % เป็นต้น.
    • ต้องรับอักขระที่เป็นเครื่องหมายคณิตศาสตร์ โดยจะมีตัวเดียวหรือมากกว่าก็ได้ เช่น + - * / เป็นต้น.
    • ควรรับอักขระที่เป็นสัญลักษณ์ต่างๆ โดยจะมีตัวเดียวหรือมากกว่าก็ได้ เช่น ✿ 🚗 🛩 🏢 ▶ ⟰ เป็นต้น.
    • ควรรับอักขระที่เป็น unicode เช่น ตัวอักษรภาษาไทย, ภาษาจีน, ภาษาญี่ปุ่น เป็นต้น.
    • ควรรับอักขระที่เป็นช่องว่าง (space) ปะปนอยู่กับอักขระอื่นๆตามเงื่อนไขด้านบน.
  • ห้ามรับอักขระที่เป็นช่องว่างล้วน (space) โดยไม่มีอักขระอื่นๆเลย.
  • ไม่ควรรับรหัสผ่านที่อยู่ในรายการต้องห้าม เนื่องจากไม่มีความปลอดภัย ตัวอย่างรายการต้องห้าม (จากคห.ของผู้เขียน - ทั้งนี้อาจจะห้ามไปเลยถ้าหากระบบนั้นต้องการความปลอดภัยมากขึ้น).
  • ห้ามรับรหัสผ่านที่ตรงกับข้อมูลผู้ใช้อื่นๆ เช่น ตรงกับอีเมล, ตรงกับชื่อผู้ใช้ เป็นต้น.
  • ห้ามป้องกันการ copy & paste รหัสผ่าน เนื่องจากผู้ใช้จำนวนมากใช้วิธีสร้างรหัสผ่านจากแอปพลิเคชันหรือปลั๊กอิน โดยให้สร้างรหัสผ่านที่ยาวและจำได้ยาก (เดาได้ยากด้วย) ซึ่งต้องอาศัยการ copy & paste เท่านั้น. การป้องกัน copy & paste จะทำให้เป็นอุปสรรคและบังคับให้ผู้ใช้หันไปตั้งรหัสผ่านที่พิมพ์ง่ายๆจำง่ายๆแทน ซึ่งกลายเป็นอันตรายมากกว่ามีผลดี.

การเก็บรหัสผ่าน

  • ต้องถูกผ่านการ hash (เพื่อที่จะให้อ่านไม่ได้) ทางเดียวเท่านั้น จะต้องไม่สามารถถูกทำย้อนกลับมาในสภาพที่อ่านได้อีก.
  • ควรผ่านการ hash โดยใช้วิธีการ (algorithm) ใดวิธีหนึ่งเหล่านี้. ตัวเลือกจากด้านบนสุดคือดีที่สุด ตามลำดับ.
    • Argon2
    • PBKDF2
    • scrypt
    • bcrypt

สำหรับผู้เขียนภาษา PHP

นโยบายด้านความปลอดภัยต่างๆ

สำหรับผู้พัฒนาระบบที่ต้องการความปลอดภัยสูงมากขึ้น แนะนำให้เพิ่มเติมและหลีกเลี่ยงสิ่งเหล่านี้ตามความเหมาะสม.

  • ไม่ควรกำหนดอายุรหัสผ่าน เช่น ให้เปลี่ยนรหัสผ่านทุกๆ 90 วัน เป็นต้น เพราะจะสร้างความรำคาญอย่างมากให้กับผู้ใช้ และผลักให้ผู้ใช้ต้องตั้งรหัสผ่านที่ง่ายๆ, หรือไม่ปลอดภัย เพื่อตัดความน่ารำคาญนี้. (จากคห.ของผู้เขียน - ไม่แนะนำอย่างยิ่ง เนื่องจากถ้าไม่มีการป้องกันที่ดีพอก็ถูกเจาะได้ในเวลารวดเร็วอยู่ดี).
  • ควรมีการป้องกันสุ่มโจมตีรหัสผ่าน (brute-force attack). โดยหลักการคือ ผู้โจมตีจะรู้ชื่อผู้ใช้ แล้วเขียนโปรแกรมขึ้นมาสุ่มรหัสผ่านยิงเข้าฟอร์ม ทำไปเรื่อยๆจนกว่าจะถูก. วิธีการโจมตีแบบนี้สามารถทำได้โดยสุ่มรหัสผ่านจำนวนมากในเวลา 1 วินาที, การป้องกันเช่น เมื่อผิดพลาดเกิน 3 ครั้งให้รอ 15 นาที เป็นต้น. หรือศึกษาเพิ่มเติมจากตัวอย่าง PHP device cookies.
  • ควรมีการกรองบอท (bot) ออกไป. วิธีนี้อาจใช้เทคนิค captcha, honeypot เข้ามาช่วย.
  • อาจจะเก็บรหัสผ่านเก่าทุกครั้งที่มีการเปลี่ยนรหัสผ่านใหม่ (ในรูปแบบ hash) และป้องกันไม่ให้รหัสผ่านเก่าถูกนำมาใช้อีก (จากคห.ของผู้เขียน - วิธีนี้ดูเหมือนเว็บไซต์ ebay.com จะใช้อยู่ ซึ่งมันก็ช่วยป้องกันไม่ให้ใช้รหัสผ่านเก่าที่อาจถูกเปิดเผยหรือรั่วไหลไปแล้วได้ดี).
  • ควรใช้การตรวจสอบขั้นที่ 2 (ศึกษาได้จากคำค้น 2 Factor authentication, Multi factor authentication, OTP).
    • อาจใช้แอปพลิเคชันบนมือถือ เช่น Authenticator หรืออาจะใช้วิธีสร้างตัวเลขไม่เกิน 9 หลักส่งไปทางอีเมล (email), SMS แล้วให้กรอกค่านี้ให้ถูกต้อง.
    • ต้องกำหนดอายุของมันด้วย เช่น ให้กรอกภายใน 5 นาทีเป็นต้น.

กรณีลืมรหัสผ่าน

  • ห้ามใช้คำแนะนำ (hint) เมื่อลืมรหัสผ่าน. เพราะกรณีเลวร้ายเคยเกิดขึ้นมาแล้วในอดีต.
  • ไม่ควรใช้คำถามเมื่อลืมรหัสผ่าน. การให้ตอบคำถามเมื่อลืมรหัสผ่านไม่ช่วยอะไรเลยในเรื่องความปลอดภัย และจะทำให้ถูกเข้าสู่ระบบโดยผู้โจมตีได้ง่ายขึ้นอีก ตัวอย่างเช่น นาย ก มีเพื่อนคือ นาย ข, นาย ก ไม่ต้องการให้นาย ข มาเข้าสู่ระบบเพื่อซื้อของ แต่เพราะนาย ข สนิทกับนาย ก จึงสามารถตอบคำถามส่วนตัวเมื่อลืมรหัสผ่านได้ถูกต้องทั้งหมด ทำให้นาย ข แอบเข้าสู่ระบบได้เลยทันที.
  • ควรใช้วิธีการตั้งค่ารหัสผ่านใหม่ (reset password).
    • ใช้การส่งลิ้งค์ไปทางอีเมลเจ้าของบัญชีเพื่อตั้งค่ารหัสผ่านใหม่.
      • ต้องมีค่าเฉพาะแนบไปกับลิ้งค์ เพื่อป้องกันการเรียกโดยตรง.
      • ต้องกำหนดอายุของมันด้วย เช่น ให้กรอกภายใน 5 นาทีเป็นต้น.
    • หรือใช้การส่งรหัสผ่านครั้งเดียว (OTP) ทาง SMS เพื่อตั้งค่ารหัสผ่านใหม่.
      • ต้องกำหนดอายุของมันด้วย เช่น ให้กรอกภายใน 5 นาทีเป็นต้น.

ควบคุม session การเข้าสู่ระบบ

  • ควรเก็บประวัติการเข้าสู่ระบบโดยละเอียด เช่น วัน-เวลา, สถานที่, หมายเลขไอพี เป็นต้น.
  • อาจจะกำหนดให้ 1 ผู้ใช้เข้าสู่ระบบได้เพียง 1 session เช่น เข้าสู่ระบบบนคอมพิวเตอร์เครื่องเดียวกันแต่ใช้ Firefox ก็จะเข้าอีกโดยใช้ Chrome ไม่ได้.
  • ควรให้ควบคุมการเข้าสู่ระบบ หรือบังคับให้ออกจากระบบได้โดยผู้ใช้นั้นๆ กรณีอนุญาตให้เข้าสู่ระบบได้มากกว่า 1 session. ตัวอย่างเช่น ผู้ใช้ ก เข้าสู่ระบบจากคอมพิวเตอร์ที่บ้านในกรุงเทพฯ จากนั้นไปเที่ยวเชียงใหม่และเข้าสู่ระบบจากคอมพิวเตอร์ของโรงแรมแล้วลืมออกจากระบบ ผู้ใช้ ก สามารถเข้าสู่ระบบบนมือถือแล้วสั่งให้ออกจากระบบทั้งหมด หรือออกจากระบบเฉพาะเครื่องคอมพิวเตอร์ที่โรงแรมก็ได้.

อ้างอิง

  1. Password length & complexity
  2. Password policy
  3. Password Storage Cheat Sheet
  4. 2016 NIST’s new password rules
  5. Digital identity guidelines
  6. Password Rules Are Bullshit
  7. password complexity policy for non “English” passwords
  8. what are good requirements for a password
  9. PHP Security: Passwords
  10. 9 Password Storage Best Practices

ใส่ความเห็น

อีเมลของคุณจะไม่แสดงให้คนอื่นเห็น ช่องข้อมูลจำเป็นถูกทำเครื่องหมาย *

คุณอาจใช้แท็กHTMLและแอททริบิวต์เหล่านี้: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>