บทความ “การเข้ารหัสลับ (Encryption) เบื้องต้น สำหรับนักพัฒนา” นี้ใช้แหล่งข้อมูลส่วนใหญ่จาก e-book ชื่อ Practical Cryptography for Developers อวจ: ที่อยู่ในบทความนั้นย่อมาจาก เอาไว้จำ จุดประสงค์ของผู้เขียนมีไว้เพื่อสรุปความสำหรับผู้อ่านที่มีความเข้าใจอยู่บ้างแล้ว หรืออ่านหัวข้อนั้นแล้วให้สามารถจำนิยามของหัวข้อนั้นได้ สาร ในบทความนี้ไม่ใช่ สารเคมี แต่เป็นข้อความ (message) ในปัจจุบันอินเทอร์เน็ตเข้ามาเป็นส่วนหนึ่งของชีวิตทุกคน แต่กระนั้นความสะดวกสบายที่มาพร้อมกับอินเทอร์เน็ต ก็ไม่ได้นำมาเฉพาะข้อดีเพียงอย่างเดียว หากมองในด้านความปลอดภัยด้วยนั้น อินเทอร์เน็ตจึงเป็นเหมือนดาบสองคม เนื่องจากว่าหากนักพัฒนา หรือผู้ใช้งานขาดความเข้าใจ ก็จะทำให้เกิดช่องโหว่ให้ผู้ไม่ประสงค์ดีโจมตีระบบ หรือเกิดการโจรกรรมทางไซเบอร์ได้ และหนึ่งในหัวใจสำคัญของการสื่อสารระหว่างผู้ใช้งาน (Client) กับแม่ข่าย (Server) นั่นก็คือ การเข้ารหัสลับ (Encryption) โดยบทความนี้จะค่อย ๆ ปูนิยามของศัพท์ต่าง ๆ ที่เกี่ยวข้อง เช่น การเข้ารหัส (Encoding), ฟังก์ชันแฮช (Hashing function) เป็นต้น จนนำไปสู่เรื่องการเข้ารหัสลับ (Encryption) ทีละหัวเรื่อง ดังต่อไปนี้ การเข้ารหัส (Encoding) อวจ: ด <-> d ; เสียง “ด” ในภาษาไทย คือเสียง “d” ในภาษาอังกฤษ ผู้เขียนใช้ภาษาไทยว่า การเข้ารหัส เพื่อแปลคำว่า Encoding และ การเข้ารหัสลับ เพื่อแปลคำว่า Encryption เนื่องจากทั้งสองสิ่งนี้แตกต่างกันอย่างมาก การเข้ารหัสนั้นไม่ได้ทำเพื่อรักษาความลับของสาร แต่ทำเพื่อความสะดวกในการรับส่งสาร หรืออ่านสารได้ง่ายขึ้น ตัวอย่างเช่น การแปลงเลขฐานสองเป็นฐานสิบ หรือการแปลงเลขฐานสิบเป็นสายอักขระ (byte array) หรือการแปลงสายอักขระเป็นสาร base64 เป็นต้น การเข้ารหัสนั้น สามารถย้อนกลับได้ง่ายด้วย การถอดรหัส (Decoding) ถ้าหากเรารู้ว่าสารที่เรารับมาถูกเข้ารหัสมาแบบใด เราก็จะสามารถถอดรหัสสารนั้นเป็นสิ่งที่เราต้องการได้ เช่น การแปลงสาร base64 เป็นสายอักขระ ตัวอย่าง การเข้ารหัสจากสายอักขระเป็นสาร base64 และถอดรหัสจากสาร base64 เป็นสายอักขระ ในภาษา python เกร็ด: ภาษาคาราโอเกะ ภาษาลู หรือคำผวน ก็เป็นการเข้ารหัสเช่นกัน 🙂 ฟังก์ชันแฮช (Hashing function) อวจ: คิดถึง -> 345e28e423062ecb7dad358f1b47e4abb836a0cd77cf9f47cf6e6478f8d43403 ; ให้แฮชของความคิดถึง แทนความซาบซึ้งในใจ (เพราะจำไม่ได้ 555) การแฮชนั้นคล้ายกับการเข้ารหัสตรงที่ ถ้าเรามีสาร และฟังก์ชันการแฮช เราก็สามารถ ผลิต เลขแฮชได้ แต่กลับกัน หากเราได้เลขแฮชมา เราจะไม่สามารถรู้ได้ว่า สารก่อนเข้าฟังก์ชันแฮชเขียนไว้ว่าอย่างไร ซึ่งจะนำไปสู่คุณสมบัติของฟังก์ชันแฮช คุณสมบัติของฟังก์ชันแฮชนั้นมีสองประการ คือ คำว่า แทบจะไม่มีสิทธิ์ชนกัน นั้น แน่นอนว่าอาจจะเกิดการชนกันได้ แต่เกิดขึ้นยาก อภิมหาโคตรยาก เรียกว่า การพยายามจะหาสารสองอันที่จะให้ผลลัพธ์เลขแฮชเดียวกัน ก็เหมือนกับการควานหาฝุ่นในจักรวาลก็ปานนั้น แต่ในอนาคตก็ไม่แน่ว่า Quantum Computer อาจจะทำให้ SHA-2 ที่ได้รับความนิยมอยู่ในปัจจุบันถูกโค่นลงได้สักวัน อันนี้ก็เป็นเรื่องของอนาคตที่เราต้องติดตามกันต่อไป ตัวอย่าง ฟังก์ชันแฮชในภาษา python ในที่นี้ ผู้เขียนขอใช้ตัวอย่างฟังก์ชัน sha256 หรือ SHA-2 มาเป็นตัวอย่าง เกร็ด: ยังมีกลุ่มฟังก์ชันที่มีแนวคิดคล้ายกับฟังก์ชันแฮชอีกสองอย่าง คือ check digit และ checksum แต่ต่างกันตรงความยากในการชนกัน เช่น หมายเหตุ: วิธีการคำนวน check digit นำมาจาก ที่นี่ จะสังเกตว่า การคำนวน check digit นั้นสามารถเกิดผลลัพธ์ที่ชนกัน (หรือเหมือนกันจากในตัวอย่างคือเลข หนึ่ง) ได้ค่อนข้างง่าย ส่วน checksum นั้นจะเกิดผลลัพธ์ที่ชนกันค่อนข้างยาก ตัวอย่างคือ SHA-1 ในอดีตฟังก์ชันนี้ถูกใช้เพื่อเป็นฟังก์ชันแฮชด้วย แต่ปัจจุบันมีผู้ที่สามารถหาผลลัพธ์ที่ทำให้เกิดผลลัพธ์ที่เหมือนกันได้แล้ว ดังนั้น SHA-1 จึงไม่ดีพอที่จะใช้เป็นฟังก์ชันแฮชเพื่อความปลอดภัยอีกต่อไป อย่างไรก็ดี SHA-1 นั้นยังมีการใช้เพื่อทำ checksum เพื่อตรวจสอบความถูกต้องของไฟล์อยู่ ฟังก์ชัน MAC อวจ: mac_func(สาร, รู้กันแค่เรา) -> ตัวเทียบว่าสารถูกต้อง ; นายเอส่งจดหมายรัก(สาร)หาน้องบีโดยใช้กระดาษสองแผ่นเสมอ(รู้กันแค่เรา) แต่วันหนึ่งไปรษณีย์ทำปลิวหายไปแผ่นหนึ่ง น้องบีจึงรู้ว่าจดหมายนั้นไม่ครบถ้วน(ไม่ถูกต้อง)เพราะไม่ครบสองแผ่น MAC ในที่นี้ย่อมาจาก Message Authenticaion Code ไม่ได้เกี่ยวข้องกับ MAC Address หรือ Media Access Control Address แต่อย่างใด MAC มีไว้เพื่อทำหน้าที่พิสูจน์ว่าสารที่เราได้รับมาถูกต้องสมบูรณ์หรือไม่ เนื่องจากการคำนวน MAC โดยวิธีใช้ hash_func(key + msg) นั้นไม่ปลอดภัยจากการโจมตีแบบ Length Extension Attack ดังนั้นฟังก์ชัน MAC ที่ปลอดภัยและได้รับความนิยมคือ HMAC (Hash-based MAC) โดยมีหน้าตาคือ mac = HMAC(key, msg, hash_func) ตัวอย่างฟังก์ชัน HMAC ในภาษา python ฟังก์ชัน KDF อวจ: kdf_func(เกลือ, รหัสผ่าน, อย่างอื่นถ้ามี) -> รหัสผ่านที่แปลงแล้ว KDF ย่อมาจาก Key Derivation Functions ฟังจากชื่อแล้วแอบน่ากลัวว่าจะเกี่ยวกับ Derivative ในคณิตศาสตร์ใช่ไหม แต่ไม่ใช่เช่นนั้น ฟังก์ชันนี้ไม่ได้เกี่ยวกับการคำนวน Derivative ผู้อ่านจึงไม่ต้องกังวล โดยในหัวข้อนี้จะพาผู้อ่านสู่ความเข้าใจ KDF ผ่านการจัดการรหัสผ่านระดับต่าง ๆ ในการจัดการรหัสผ่าน (password) นั้นแน่นอนว่าเราไม่สามารถหลีกหนีเรื่องความปลอดภัยไปได้ และการเก็บรหัสผ่านของผู้ใช้ที่สามารถนำไปใช้งานกับระบบได้ทันทีก็เปรียบเสมือนการเก็บระเบิดเวลาไว้ในระบบ ผู้เขียนขอกล่าวถึง การจัดการรหัสผ่านโดยเริ่มตั้งแต่ระดับ อย่าหาทำ ไปจนถึงระดับ ควรทำ ระดับ อย่าหาทำ หรือเกรียนสุด วิธีการที่ง่ายสุด (และเกรียนที่สุดด้วย) นั่นคือการเก็บรหัสผ่านแบบ โต้ง ๆ ได้มาอย่างไรก็เก็บไปอย่างนั้นซะเลย ตัวอย่างเช่น ผู้ใช้งานกรอกรหัสผ่านตอนลงทะเบียนมาเป็น “hello123” ก็นำรหัสผ่านนี้เขียนลงในฐานข้อมูลตารางผู้ใช้เป็น “hello123” นั่นเอง แม้ว่าการจัดการรหัสผ่านของผู้ใช้โดยวิธีนี้จะไม่มีความซับซ้อน และไม่ต้องใช้...