การเก็บรหัสผ่านที่ถูกต้อง
🤔 ถ้าเราต้องเก็บความลับของลูกค้าไว้ เราจะต้องเก็บยังไงถึงจะเรียกว่าปลอดภัย?
Last updated
Was this helpful?
🤔 ถ้าเราต้องเก็บความลับของลูกค้าไว้ เราจะต้องเก็บยังไงถึงจะเรียกว่าปลอดภัย?
Last updated
Was this helpful?
ในบทความนี้เราจะมาดูกันว่า การเก็บความลับไว้ในฐานข้อมูลนั้น ขั้นต่ำ ที่เรียกว่าปลอดภัยจริงๆมันเป็นยังไง ซึ่งในบทความนี้จะไม่ได้ลงรายละเอียดว่าต้องทำยังไงบ้าง แต่จะให้เข้าใจแนวคิดพื้นฐานในการเพิ่มความปลอดภัยให้กับระบบนะฮ๊าฟ
เว็บไซต์ เฟสปาล์ม ได้เปิดตัวบริการ Social Media ที่สั่นสะท้านวงการ ทำให้มีคนนับล้านๆคนเข้าไปใช้บริการอย่างล้นหลา จนมียอดผู้ใช้ทะลุหลัก 1,000 ล้านคนภายในเวลาไม่นาน จนกระทั่งวันหนึ่งก็มีข่าวช๊อกโลก เพราะมีคนจับได้ว่าเฟสปาล์มได้ทำการขายข้อมูลผู้ใช้ให้กับบริษัทต่างๆ เลยทำให้ Hacker ทั่วโลกโกรธเกรี้ยวบริษัทเฟสปาล์มเป็นอันมาก และหนึ่งในบรรดา Hacker ก็เจาะเข้าระบบฐานข้อมูล ดึงข้อมูลผู้ใช้ออกมาได้ส่วนนึง ทำให้มีผู้ใช้หลายล้านรายที่ตกเป็นเหยื่อ เพราะถูกล่วงรู้ รหัสผ่าน และแม้กระทั่งข้อมูลบัตรเครดิตนั่นเอง
ดังนั้นบริษัทเฟสปาล์มเลยต้องมาวางแผนรับมือไม่ให้เกิดปัญหาที่ว่ามานี้อีก โดยสิ่งที่แรกเอามาดูก็คือ ข้อมูลผู้ใช้ที่อยู่ในฐานข้อมูล มันเป็นประมาณนี้
Id
Username
Password
1
saladpuk
1234
2
thaksin
homesick
3
prayut
1234
เจ้าหน้าที่รักษาความปลอดภัยที่ชื่อ ยิน เห็นแล้วได้ถึงกับตกใจแล้วพูดออกมาว่า
พูดไม่ทันขาดคำ เจ้าหน้าที่รักษาความปลอดภัยที่อยู่ข้างๆที่ชื่อ วอดก้า ก็พูดแทรกขึ้นมาว่า มันจำเป็นต้องเก็บเป็น plain text ไว้ เพราะเวลาลูกค้าโทรมาบอกว่าลืมรหัสผ่าน เราก็จะได้เอารหัสผ่านให้เขายังไงล่ะ
ยิน ได้ฟังคำตอบก็ถึงกับทรงกริ้วและบอกว่า ก็นี่ยังไงล่ะปัญหาที่เกิดขึ้น เพราะถ้ามีคนเจาะระบบเข้ามาได้ เขาก็จะได้ข้อมูลทุกอย่างไปเลยแบบชิวๆอะดิ มันเหมือนกับเอ็งวางเงินสดไว้กลางบ้านเลยยังไงล่ะ ถ้าโจรเข้ามาในบ้านได้มันก็เปรมเลยเพราะไม่ต้องเสียเวลาเจาะตู้เซฟก็ฉกเงินออกไปได้เลยนั่นเอง ดังนั้นเราจะต้องแก้เรื่องนี้ซะ
แม้ วอดก้า จะหงุดหงิดได้แต่คิดในใจว่า "ทำไมเอ็งไม่ไปแก้ให้มันเจาะไม่ได้แทนฟระ?" แต่เขาก็ไม่ได้พูดออกมา ได้แต่ก้มหน้าเพิ่มให้ระบบต้องทำการเข้ารหัสตัว password ก่อนที่จะเอาไปเก็บลงฐานข้อมูล โดยใช้ DES ในการเข้ารหัส ซึ่งทำให้ฐานข้อมูลเป็นแบบนี้ (ผลลัพท์เป็นแบบสมมุตินะ)
Id
Username
Password
1
saladpuk
A1B2C3D4
2
thaksin
CF67D00569ACC1
3
prayut
A1B2C3D4
ยิน มองข้อมูลในฐานข้อมูลตาถลน พร้อมกับตะโกนบอก วอดก้า ไปว่า
วอดก้า งง เป็นไก่ตาแตกเพราะไม่รู้ว่าจะต้องเข้ารหัสยังไงดี เลยทำให้ เบลม็อท เข้ามาช่วยอธิบายให้ฟังเป็นข้อๆว่า Data Encryption Standard (DES) ที่ วอดก้า ใช้ในการเข้ารหัส มันเป็นรุ่นสมัยก่อนที่เขาไม่ใช้กันแล้ว (56-bits key) เพราะมันตั้งแต่ 1999 มันใช้เวลาแค่ 22 ชั่วโมงนิดๆก็สามารถถอดรหัสกลับมาได้แล้วยังไงล่ะ ดังนั้นจงเลือก algorithm ที่เหมาะสมกับมันด้วย ไม่ใช่ตะบี้ตะบันเจอใน Stackoverflow ตัวไหนก็จับมายัดใส่เลย ดังนั้นจงไปศึกษาเพิ่มซะ
เบลม็อท ชี้ให้เห็นรหัสผ่านของเจ้า saladpuk กับ prayut ว่าผลลัพท์มันได้เป็นค่าเดียวกันเลย เพราะถ้าเก็บเป็นแบบนี้ เมื่อมีคนถอดรหัสของใครซักคนได้ เขาก็จะรู้รหัสผ่านของคนอื่นๆที่ใช้รหัสแบบเดียวกันทันทีเลยอะดิ ดังนั้นถ้าต้องการให้ ความลับที่เป็นค่าเดียวกัน แต่ได้ผลลัพท์ต่างกัน เราก็สามารถใส่ของมั่วๆเข้าไปในความลับนั้นก็ได้ โดยเราเรียกมันว่า Salt หรือ Nonce (number used only once) นั่นเอง
เป็นการสุ่มอะไรมั่วๆซักอย่างเข้าไปต่อกับสิ่งที่เราต้องการให้เป็นความลับ เช่น รหัสผ่านของ saladpuk คือ 1234 เราก็อาจจะสร้าง salt ออกมาเป็น su!sC* แล้วเอามันไปต่อท้ายหรือไว้ก่อนหน้าก็ได้เลือกเอาซักอย่าง เราก็จะได้ผลลัพท์ออกมาเป็น 1234su!sC* (ในตัวอย่างคือเอาไปต่อท้าย) ซึ่งผู้ใช้แต่ละคนก็จะต้องมี salt เป็นคนละตัวกันด้วยนะ ดังนั้น รหัสผ้านของ prayut คือ 1234 เราก็จะสร้าง salt ออกมาอีกตัวสมมุติว่าเป็น A#$563d เราก็เอามันมาต่อท้ายก็จะออกมาเป็น 1234A#$563d ดังนั้นพอเอาค่าทั้ง 2 ตัวนี้มีผ่านการ HASH เราก็จะได้ผลลัพท์ที่ไม่เหมือนกันยังไงล่ะ ตามรูปเลย
Id
Username
Password
Salt
1
saladpuk
fd4438f5b856bb685004b84221ba794b
su!sC*
2
thaksin
f679b30fde31dff10304dc357300c52b
$%Acdes
3
prayut
3d54cf99f817a21cd9fd2b7218e58fec
A#$563d
ในการเก็บข้อมูล เราก็จะทำการเก็บ salt ที่เราสร้างให้กับผู้ใช้แต่ละคนเอาไว้ด้วยนะ
เบลม็อท พูดต่อว่า ถ้าใครอยากจะถอดรหัสความลับต่อให้เป็นระบบตัวเองก็ตาม ก็ต้องเพิ่มความยากในการถอดรหัส ให้มันเสียเวลาในการถอดรหัสนานที่สุดเท่าที่จะทำได้ด้วย โดยหนึ่งในหลักการที่ช่วยได้คือการทำสิ่งที่เรียกว่า Pepper นั่นเอง
หลักการเหมือนกับ salt เลยคือสุ่มของมั่วๆขึ้นมาซักตัว แต่จะสุ่มแค่ 1 ตัวอักษร อาจจะเป็นตัวเล็กหรือตัวใหญ่ก็ได้ เพื่อเอาไปต่อกับความลับของเราให้มันยาวขึ้น เวลาที่เอาไป HASH มันจะได้ผลลัพท์ออกมาไม่เหมือนเพื่อนนั่นแต่ แต่จะต่างกันคือ มันจะไม่เก็บค่า papper ไว้ที่ไหนอีกเลย ดังนั้นเวลาที่เราจะตรวจสอบว่าผู้ใช้ ใส่รหัสผ่านถูกหรือเปล่า ระบบจะต้องเสียเวลาในการไปสุ่มตั้ง a-z และ A-Z ซึ่งถ้ามีผลลัพท์ไหนตรงกับรหัสผ่านที่เก็บไว้ ก็แสดงว่ารหัสผ่านที่ส่งเข้ามาถูกต้องนั่นเอง
เป็นเรื่องสุดท้ายที่ เบลม็อท กล่าวทิ้งท้ายไว้ ซึ่ง ยิน ได้ช่วยอธิบายก่อนที่จะไม่มีบทพูดในเรื่องนี้ว่า ถ้าเราทำการเข้ารหัสหรือถอดรหัสโดยมีการบันทึกข้อมูลไว้ใน disk นั่นหมายความว่าถ้า disk ก้อนนั้นหลุดออกไป หรือ แม้กระทั่งคนภายในแอบเข้ามากู้ข้อมูลใน disk ออกไป นั่นก็หมายความว่าระบบก็ยังมีความเสี่ยงอยู่ดี ดังนั้นทุกสิ่งทุกอย่างในการเข้ารหัสถอดรหัส เราควรทำไว้ใน Memory เท่านั้น เพราะมันจะไม่ทิ้งหลักฐานอะไรไว้อีกเลย
ยิน ได้กล่าวทิ้งท้ายไว้ พร้อมกับบอกว่า เอ็งจะมั่นใจได้ยังไงว่าของที่เขียนเองมันปลอดภัย ดังนั้นจงไปหา library ที่ใช้ในการจัดการเรื่องนี้โดยเฉพาะจะดีกว่า เพราะส่วนใหญ่เขาจะมีการตรวจสอบอยู่ตลอดเวลา และเมื่อไหร่ที่มีอัพเดทว่าตัวนี้ไม่เหมาะสมแล้ว หรืออะไรก็ตาม ส่วนใหญ่เขาก็จะอัพเดท library เพื่ออุดรูรั่วเหล่านั้น ทำให้ระบบของเราได้รับผลพลอยได้ไปด้วยนั่นเอง
ไม่ต้องทำก็ได้นะ แต่เป็นคุณเองจะอยากใช้เว็บที่เก็บข้อมูลบัตรเครดิตของคุณไว้ โดยที่มันทำแค่เพียงครึ่งนึงของที่ผมพูดหรือเปล่า? ถ้าไม่คำตอบก็ชัดเจนอยู่แล้วว่าทำไมต้องทำ ซึ่งในปัจจุบันของที่เหล่า hacker ใช้เป็นตัวพื้นฐานของเขาเลยคือ
เป็นตารางที่ถูกคำนวนไว้เรียบร้อยหมดแล้วว่า ถ้าผลลัพท์ในการ HASH เป็นแบบนี้ แสดงว่าข้อความที่เป็น plain text คืออะไรนั่นเอง ดังนั้นถ้าเราใช้ HASH กากๆ ที่มันตกยุกต์แล้ว เหล่า hacker แทบจะยิ้มตุ่ยเลยทีเดียว เพราะมันไม่ต่างกับการเก็บ plain text ไว้เลยยังไงล่ะ
เป็นข้อมูลที่รวบรวม HASH รหัสผ่านที่คนชอบใช้กัน ดังนั้นถ้าเราใช้รหัสผ่านที่คนอื่นใช้เหมือนๆกับของเรา แล้วตัวระบบดันไปเก็บค่า hash แบบเดียวกันอีก ก็หวานหมูเลย
เป็นการพยายามหาคำตอบโดยแทยที่ทุกความเป็นไปได้ลงไป เช่น แทนค่าตั้งแต่ aaaaaaaa~ZZZZZZZZZ ไรงี้ เพื่อให้ฟลุ๊คแล้วเจอผลลัพท์ที่ตรงกับ HASH ที่เก็บไว้นั่นเอง ซึ่งปัจจุบันตัว PIN ก็พึ่งเป็นข่าวว่าโดนโจมตีโดยใช้เจ้าตัวนี้อยู่ เพราะมันเป็นแค่ตัวเลขไม่เกิน 8 หลักไรงี้ไง
เมื่อหลายปีก่อน เครื่องถอดรหัสสามารถถอด HASH ได้ราวๆ 1,000,000,000 ล้านตัวต่อ 1 วินาที ดังนั้นไม่น่าแปลกใจเลยใช่ไหมว่าทำไมเราต้องทำให้รหัสผ่านมันต้องใช้เวลาให้ถอดรหัสนานที่สุดเท่าที่เป็นไปได้
การเก็บรหัสผ่านไว้ในฐานข้อมูลจริงๆมีอีกหลายเรื่องที่อยากจะเล่าให้ฟัง ดังนั้นในบทความหน้าเดี๋ยวเรามาลองดูกันว่า แค่เรื่องการ Login เข้าสู่ระบบธรรมดาๆที่พบได้ทั่วไป เชื่อไหมว่าเบื้องหลังจริงๆมันไม่ได้ง่ายแบบนั้นนะถ้าเราต้องเอาเรื่อง security เข้ามาใช้ด้วย
จากนิทานที่เล่าให้ฟังไป เราก็จะพบว่าการเก็บความลับไว้ในระบบนั้น มันไม่ใช่ทำแบบขอไปทีแล้วมันก็จะจบนะ ดังนั้นขอสรุปคร่าวๆก่อนละกัน
ห้ามเก็บความลับเป็น plain text
แม้กระทั่งคนภายในของเราเองก็ต้องห้ามรู้รหัสลับต่างๆที่เก็บไว้ในฐานข้อมูล
การถอดรหัสควรจะต้องใช้เวลาในการถอดรหัสนานที่สุดเท่าที่จะทำได้
รหัสผ่านแม้จะเป็นรหัสเดียวกันก็ต้องเก็บลงในฐานข้อมูลเป็นคนละตัวกัน
ห้ามให้ใครเดาได้ว่ารหัสผ่านแต่ละคนยาวสั้นต่างกัน
การเข้ารหัสถอดรหัสต่างๆควรทำใน Memory ห้ามมาทำไว้บน disk
ให้ใช้ Security Library ที่สากลเขาใช้ ดีกว่าเขียนเองเสมอ
เบลม็อท ชี้ไปที่รหัสผ่านของเจ้า saladpuk กับ thaksin แล้วพูดว่า ดูปุ๊ปก็พอจะเดาได้ว่ารหัสผ่านของ saladpuk น่าจะสั้นกว่าของ thaksin ดังนั้นถ้าเขารู้รหัสผ่านของ thaksin เขาก็จะรู้แนวทางในการใส่รหัสผ่านของคนอื่น ที่สั้นหรือยาวกว่าของ thaksin นั่นเอง พูดจบ เบลม็อท ก็เปิดบทความของ สลักผัก ขึ้นมาให้อ่านเรื่องการใช้ HASH เพื่อแปลงข้อความให้มันมีความยาวเท่ากันเสมอ (ถ้าลืมไปแล้วหรืออยากทบทวนก็กดไปอ่านจากตรงนี้ซะ )