การเก็บรหัสผ่านในระบบ ไม่ควรเก็บรหัสผ่านไว้ตรงๆ ถ้า user ใช้รหัสผ่าน 1234 ก็ไม่ควรบันทึกข้อมูล 1234 ลงไป มี 2 เหตุผลคือ
- ถ้าโดนขโมยข้อมูลในฐานข้อมูลไป hacker cracker จะรู้ทั้งหมดว่าใครใช้รหัสผ่านอะไร แต่เราอาจจะไม่รู้ว่าโดนเล่นไปแล้ว จนมีความเสียหายออกมา (sony, apple, microsoft, กระทรวงกลาโหมสหรัฐโดนมาหมดแล้ว ถึงจะเป็นเว็บเล็กๆ ก็ไม่มีเหตุผลอะไรที่จะคิดว่า ถ้า hacker จะทำจริงๆ แล้วเว็บเราจะปลอดภัย)
- ถ้ามีการทำงานอะไรผิดพลาดขึ้นมาก็จะไม่มีใครพูดว่า ฉันไม่ได้ทำ ฝ่าย it นั่นละทำรึเปล่า ก็รู้รหัสผ่านของทุกคนไม่ใช่เหรอ (เคยเจอปัดความรับผิดชอบง่ายๆ แบบนี้จริงๆ ตอนนั้นโชคดีที่มี ip log ช่วยไว้)
ใน PHP จะนิยมใช้ md5 เข้ารหัสแปลง password เป็นตัวอักษร 32 ตัวอักษรที่อ่านยังไงก็ดูไม่ออกว่าต้นฉบับคืออะไร แต่เพราะว่ามันเป็นวิธีที่ถ้าป้อนรหัสผ่านเดียวกันลงไป ก็จะได้คำตอบเหมือนเดิมทุกครั้ง ไม่ว่าจะทำในเครื่องไหน ทำให้เวลามีคนขโมยข้อมูลในตารางสมาชิกออกไปได้ จะสามารถหารหัสผ่านจริงๆ ได้ถ้าเอาไปเที่ยบกับตาราง rainbow table (ตารางที่เกิดจากการเปลี่ยนตัวอักษรไปเรื่อยๆ จากนั้นแล้วเข้ารหัสแล้วเก็บเอาไว้เปรียบเทียบหารหัสผ่านต้นฉบับ) หรือจะใช้บริการเว็บอย่าง md5decrypter, md5this ทำให้ยังไม่ปลอดภัยเท่าที่ควร
วิธีแก้คือใช้ salting ? ตอนเจอวีธีนี้ครั้งแรก งงว่ามันเกี่ยวอะไรกับเกลือ, การใส่เกลือ salting คือการเพิ่มชุดของสตริงเข้าไปในรหัสผ่านก่อนเข้ารหัส ตามตัวอย่าง
<!doctype html> <html> <head> <meta charset="utf-8"> <title>md5 salting</title> </head> <body> <?php $password = '1234'; echo '<br />password = "',$password,'"<br />MD5 ได้ <b>',md5($password),'</b><br />'; $salt = '2MnLPPdUZDHBQMYz5rB3GhMJYQRV9MyaYA3QHXEz'; echo '<br />password = "',$password,'" salt="',$salt,'"<br />MD5 ได้ <b>',md5($password.$salt),'</b><br />'; $salt = 'JnwMeUTJgMfjjM5E28jyHqQZ2JLRUnZk3FnM9zUK'; echo '<br />password = "',$password,'" salt="',$salt,'"<br />MD5 ได้ <b>',md5($password.$salt),'</b><br />', '<br />ทดลอง decode <a href="http://www.md5decrypter.co.uk" target="_blank">md5decrypter</a>'; ?> </body> </html>
จะเห็นว่าค่าที่ได้ md5 อย่างเดียวจะสามารถใช้เว็บด้านบนหารหัสผ่านได้ แต่ถ้าใส่ salt จะหาไม่ได้และถ้าเปลี่ยน salt ผลที่ได้จะไม่เหมือนกัน ช่วยให้ระบบปลอดภันขึ้น โดยถ้าอีกฝ่ายไม่ได้ salt ไปก็ยากที่จะรู้รหัสผ่านคืออะไร
ตัวอย่างระบบที่ใช้วิธีนี้คือ prestashop สมุติว่าลืมรหัสผ่านผู้ดูแลระบบเรานอกจากขอรับรหัสผ่านใหม่แล้ว สามารทำ manual reset password ได้โดย
- เปิดไฟล์ config/settings.inc.php หาค่าในตัวแปร _COOKIE_KEY_ อันนี้คือตัวแปรที่ prestashop ใช้เป็น salt ครับ
- ไปที่ phpMyAdmin เปิดตาราง xxx_employee หาชื่อ user ที่ต้องการ ที่ field password ให้ copy ค่าในตัวแปร _COOKIE_KEY_ ไปวางตามด้วยรหัสผ่านใหม่ที่ต้องการเปลี่ยน จากนั้นในช่อง function เลือก md5 บันทึก รหัสของผู้ใช้ก็จะเปลี่ยนไปตามรหัสที่เราใส่ไปหลังค่าใน _COOKIE_KEY_