เข้ารหัส Password ด้วย Hash function กับ Salt values

 

โปรแกรมเมอร์ เก็บ Password แบบไหน? ถึงจะปลอดภัย
ในทางโปรแกรมมิ่งการเก็บ password ลงฐานข้อมูล (Database) ไม่ได้เก็บกันตรงโต้งๆ ไม่งั้นใครมาเห็นก็อ่านได้หมด ซวยกันพอดี
:
วิธีเก็บ password ที่ปลอดภัย
จะนำมาผ่าน Hash function เสียก่อน เช่น
hash(“1234”) ได้คำตอบออกมาเป็น
a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9
:
หน้าที่ hash function จะแปลงพาสเวิร์ด “1234”
เป็นข้อความลับอะไรซักอย่างที่อ่านไม่ออก
ทั้งนี้ขนาดข้อความที่ได้จาก hash function จะคงที่ (fixed size)
:
สำหรับค่าที่ได้จาก Hash function มีหลายชื่อให้เรียกขาน เช่น
hash values, hash codes, digests
แต่ผมจะเรียกสั้นๆ ว่า “ค่า hash” แล้วกัน
:
ส่วนฟังก์ชั่นที่ใช้เป็น Hash function ในโลกนี้มีหลายตัว เช่น
MD5, SHA256, SHA512, RipeMD, WHIRLPOOL เป็นต้น
:
+++++
ตัดกลับมาตอนนี้เราเก็บ password ในฐานข้อมูลเป็นค่า hash
แล้วเวลายูสเซอร์ล็อกอินกรอก user name ป้อน password เข้ามาในระบบ
.
ก็จะมีสเตปการตรวจสอบ password ประมาณเนี่ย
.
1) ระบบจะเอา password มาเข้า hash funcion ได้เป็นค่า hash
2) เอาค่า hash ในข้อ 1 ไปเทียบดูในฐานข้อมูล (ของยูสเซอร์นั้น)
3) ถ้าค่าตรงกันแสดงว่ายูสเซอร์ป้อน password ได้ถูกต้อง แสดงว่าล็อกอินสำเร็จ
:
เหตุผลที่ hash function มัน ok เพราะอาศัยคุณสมบัติดังนี้
1) hash function มันทำงานทางเดียว (one-way)
หมายถึงเราไม่สามารถนำค่า hash มาย้อนหาข้อความต้นฉบับได้เลย
.
ในกรณีนี้ต่อให้ hacker เห็นค่า hash เขาจะไม่สามารถถอดกลับ
มาเป็น “1234” ได้เลย
.
ด้วยเหตุนี้ค่า hash บางทีเขาจึงเรียกว่า “message digest”
หมายถึง “ข้อความที่ย่อยสลาย” …จนไม่รู้ต้นฉบับหน้าตาเป็นแบบไหนแล้ว
:
2) ถ้าข้อความต้นฉบับหน้าตาเดียวกันเป๊ะทุกกะเบียดนิ้ว
เวลาผ่าน hash function จะได้ค่า hash เหมือนเดิม
พอเปลี่ยนข้อความต้นฉบับนิดหนึ่ง
แม่เจ้า ….ค่า hash เปลี่ยนไปราวฟ้ากับเหว ต่างกันมาก
.
จึงเป็นไปไม่ได้ที่เราจะเก็บ password ต่างกัน
แล้วได้ค่า hash เดียวกัน …เป็นไปไม่ด้ายยยย
(ไม่มีการชนกันหรือ crash)
:
+++++
เพราะข้อดีของ hash function ที่ยกมา
เวลาเก็บ password ลงฐานข้อมูล จึงควรเปลี่ยนไปใช้ค่า hash แทน
.
รับรองได้ว่าต่อให้ hacker เจาะระบบเข้ามาได้ (กรณีเลวร้ายสุดๆ แหละ)
…แล้วอ่าน password ที่ถูกเข้ารหัส ก็จะอ่านไม่รู้เรื่อง
…ต่อให้พยายามถอดกลับมาเป็นข้อความต้นฉบับ ก็ทำไม่ได้นะจ๊ะ
:
ฟังเหมือนปลอดภัยนะ ถ้าเก็บรักษา password ด้วยวิธี hash function แต่ทว่า hacker ก็ยังสามารถใช้วิธีเดาสุ่มหา password ได้อยู่ดี …ไม่ยากด้วย ขอบอกเลย
:
ยกตัวอย่างง่ายๆ วิธี hack พาสเวิร์ดเบสิกสุดๆ
– ให้คิดว่าตอนนี้ hacker เจาะระบบเข้าไปอ่าน password ในฐานข้อมูลได้แล้ว
– จากนั้น hacker จะมองหาค่า hash (ของ password) ในฐานข้อมูลที่ซ้ำๆ กันอยู่
– นั่นหมายถึงเจอยูสเซอร์ใช้ password ซ้ำกัน จึงเจอค่า hash ซ้ำกันนั่นเอง
– แล้วการที่ยูสเซอร์ใช้ซ้ำ แสดงว่ามันเป็น password ง่ายนะซิ เช่น
123456, 1111, Baseball, Qwerty, password
.
ดังนั้น hacker ก็แค่ค้นหาในตาราง
ตารางที่ว่าจะเก็บ password พร้อมค่า hash
(เก็บพวก password ที่คนใช้กันเยอะ)
ซึ่ง hacker ก็จะค้นหาหาในตารางดังกล่าว
แบบไล่สุ่มไปเรื่อยๆ เดี่ยวก็เจอไม่ยาก
:
++++
ก็เพราะเหตุนี้จึงต้องหาวิธีแก้ทาง hacker
ให้เดาสุ่มหา password มันทวีความยุ่งยากไปอีก
(จุดประสงค์ป้องเทคนิคพวกเดาสุ่ม เช่น
dictionary attacks, Brute Force Attacks, Lookup Tables,
Reverse Lookup Tables, Rainbow Tables)
:
สำหรับวิธีการป้องกัน ก็จะทำประมาณเนี่ย
ก่อนที่จะเก็บ password ลงฐานข้อมูล ระบบจะต้องทำเยี่ยงนี้
1) จะนำ password มากบวกกับค่า salt
2) จากนั้นนำค่าที่ได้จากข้อ 1 มาเข้า hash function
แล้วเก็บค่า hash ที่ได้ลงฐานข้อมูล
.
ขออธิบายข้อ 2 เพิ่มเติม
จากเดิมเราเรียกใช้ hash function เช่น
hash(“1234”)
แต่เราจะเปลี่ยนมาเรียก
hash(“1234” + “QxLUF1bgIAdeQX”)
hash(“1234” + “bv5PehSMfV11Cd”)
hash(“1234” + “YYLmfY6IehjZMQ”)
.
ซึ่ง “QxLUF1bgIAdeQX”, “bv5PehSMfV11Cd”, “YYLmfY6IehjZMQ” ที่ยกตัวอย่าง
มันก็คือค่า “salt” (ที่แปลว่า “เกลือ”)
เป็นค่า radom ที่แจกให้แต่ละยูสเซอร์ ไม่ซ้ำกันเลย
เราจะนำมาบวกกับ password ก่อนเข้า hash function
:
เวลาเก็บ password ในฐานข้อมูล
แต่ละยูสเซอร์จะต้องเก็บทั้งค่า hash กับ salt เอาไว้
.
พอเวลายูสเซอร์ล็อกอินใส่ user name / password
1) ระบบก็เอา password มาบวกกับ salt
(แต่ละยูสเซอร์เก็บค่า salt คนละค่า)
2) นำค่าที่ได้จากข้อ 1 มาเข้า hash funcion
3) นำค่าที่ได้จากข้อ 2 ไปเปรียบเทียบกับ ค่า hash ในฐานข้อมูล
4) ถ้าตรงกันแสดงว่ายูสเซอร์ป้อน password ถูกต้อง แสดงว่าล็อกอินสำเร็จ
..
แต่มีข้อแม้ hash function ที่ควรใช้ได้แก่
Argon2, bcrypt, scrypt ($2y$, $5$, $6$), หรือ PBKDF2
มันถึงจะปลอดภัย ทำให้การเดาสุ่มหา password ทำได้ยากขึ้น
.
ส่วนพวก hash function ที่ทำงานได้รวดเร็ว เช่น
MD5, SHA1, SHA256, SHA512, RipeMD, WHIRLPOOL, SHA3, etc.
เนี่ยห้ามใช้นะครับ
หรืออย่าง crypt (เวอร์ชั่น $1$, $2$, $2x$, $3$) ก็ไม่ห้ามใช้นะครับ
:
+++++
ในแง่การเขียนโปรแกรม
เข้าใจว่าแต่ละภาษาโปรแกรมมิ่ง หรือพวกเฟรมเวิร์ค
เขาคงเตรียมไลบรารี่ หรือเครื่องมือ
เอาไว้ให้ใช้ hash function รวมกับค่า salt อยู่แล้ว
เราสามารถเปิดคู่มือ แล้วทำตามได้เลยครับ
:
++++
ย้ำที่อธิบายทั้งหมดนี้
เป็นการป้องกันการเจาะระบบฝั่งแอพ หรือระบบเท่านั้น
hacker ยังสามารถเดาสุ่มป้อน password
ได้โดยตรงที่หน้าแอพ หรือฝั่งล็อกอินหน้าโปรแกรมได้เลย (Brute Force Attacks)
.
ทางที่ดีระบบต้องเช็กว่าถ้ายูสเซอร์กรอก password ผิดติดต่อกันกี่ครั้ง?
ถึงจะระงับการใช้ user name นี้ชั่วคราว หรือจะแบน IP ที่ล็อกอินเข้ามาไปเลยก็ยังได้
.
ยิ่งถ้าเป็นการล็อกอินผ่านเว็บไซต์
ก็ควรให้เว็บเราใช้โปรโตคอล https ขืนไปใช้ http ธรรมดา
โอกาสเจอ hacker ดักจับ user name/ passwod กลางทางมีสูงมาก
.
เว้นแต่เราจะใช้เทคนิค Digest Access Authentication เข้าช่วย
ทำให้การส่ง user name/password ผ่าน http ธรรมดาได้อย่างปลอดภัย (แต่โค้ดดิ่งก็จะยุ่งยากตาม)
:
+++
สรุป
1) เก็บพาสเวิร์ดตรงๆ โดยไม่เข้ารหัส -> hacker ชอบนักแล
2) เก็บพาสเวิร์ดโดยเข้ารหัสในรูป Hash values -> hacker อ่านไม่ออกก็จริง แต่ไม่ยากที่จะเดา password
3) เก็บพาสเวิร์ดโดยเข้ารหัสในรูป Hash values + salt vaues
-> hacker อ่านไม่ออก ต่อให้ไปเดาสุ่ม ก็จะทำได้ยากขึ้น
จุดประสงค์ข้อ 3 นี้เพื่อป้องกันด้วยเทคนิค ….. dictionary attacks, Brute Force Attacks, Lookup Tables, Reverse Lookup Tables, Rainbow Table
.
สุดท้ายขอจบเรื่อง hash funcion กับ password
ให้รอดพ้นจาก hacker ไว้เพียงเท่านั้น
หวังว่าจะเป็นประโยชน์ต่อทุกท่านนะครับ
.
++++++
อ้างอิง

https://crackstation.net/hashing-security.htm
https://en.wikipedia.org/wiki/Hash_function

 

?เขียนโดยแอดมินโฮ โอน้อยออก

Please like Fanpage