![]()
กระบวนการยืนยันตัวตน (Authentication) เป็นปัญหาสำคัญในโครงสร้างความปลอดภัยคอมพิวเตอร์มาต ั้งแต่เริ่มต้นยุคแรกๆ จนถึงทุกวันนี้ที่ปัญหาการขโมยตัวตนผู้ใช้ออนไลน์ยัง เป็นปัญหาอยู่เรื่อยมา การยืนยันตัวตนที่ใช้งานเป็นวงกว้างทุกวันนี้คงเป็นร หัสผ่านที่มีคุณสมบัติการยืนยันตัวตนที่ดีพอสมควร เช่น เป็นความลับส่วนตัวกับเจ้าของตัวตน, และสามารถยกเลิกได้เมื่อความลับรั่วไหล แต่อย่างไรก็ตาม เราพบว่าผู้ใช้จำนวนมากมีแนวโน้มจะใช้รหัสผ่านอย่างไ ม่ปลอดภัย เช่น การใช้รหัสผ่านที่ง่ายต่อการคาดเดาจนเกินไป รวมถึงการใช้รหัสผ่านร่วมกันกับบริการอื่นๆ ทำให้รหัสผ่านตกอยู่ในความเสี่ยงเมื่อบริการใดบริการ หนึ่งถูกเจาะจนข้อมูลรั่วไหล แฮกเกอร์มีแนวโน้มจะนำรหัสผ่านเหล่านั้นไปใช้งานกับบ ริการอื่นๆ ในทันที
กระบวนการยืนยันตัวตนแบบสองขั้นตอนออกแบบมาเพื่อเสริ มความแข็งแกร่งของกระบวนการยืนยันตัวตนจากเดิมที่อาศ ัย "ความรู้" (รหัสผ่าน) ของผู้ใช้อย่างเดียว เพิ่มเติมว่าผู้ใช้ "มีอะไร" เพื่อยืนยันตัวตน โดยขั้นตอนที่สองที่เว็บต่างๆ ให้ความนิยมกันมากทุกวันนี้คือการนำข้อความยืนยันว่า ผู้ใช้มีโทเค็นยืนยันตัวตน เช่น โทรศัพท์ อยู่กับตัว
โทเค็นยืนยันตัวตนในสมัยหนึ่งนั้นมักเป็นฮาร์ดแวร์เฉ พาะบรรจุค่าความลับมาจากโรงงาน ตัวอย่างของโทเค็นกลุ่มนี้ เช่น ซิมการ์ดโทรศัพท์มือถือที่ใช้ยืนยันตัวตนของเจ้าของเ ลขหมายได้ หรือระบบยืนยันตัวตนในเซิร์ฟเวอร์ที่เป็นสินค้าสำคัญ ของบริษัท RSA ก็มักเป็น "พวกกุญแจ" มาจากโรงงาน การทำสำเนาทำได้ยาก แต่กระบวนการแจกจ่ายโทเค็นเหล่านี้ให้กับบริการที่มี คนใช้งานจำนวนมากๆ ก็เป็นเรื่องยากและค่าใช้จ่ายสูงเป็นอย่างยิ่ง โดยเฉพาะหากเราต้องมั่นใจว่ากระบวนการจัดส่งนั้นจะไม ่ทำให้โทเค็นหลุดไปอยู่ในมือคนร้าย บริการใหม่ๆ เช่น กูเกิล, Digital Ocean, Amazon Web Service, ไปจนถึง Facebook จึงเลือกกระบกวนการที่ราคาถูกและจัดการได้ง่ายกว่า โดยที่ยังเพิ่มความปลอดภัยให้กับผู้ใช้ได้อย่างมีประ สิทธิภาพ นั่นคือการส่งความลับให้กับผู้ใช้เพื่อไปเก็บรักษาใน อุปกรณ์ใดๆ เช่น โทรศัพท์มือถือ หากผู้ใช้สามารถยืนยันได้ว่ายังมีโทรศัพท์มือถืออยู่ กับตัวก็น่าเชื่อได้ว่าผู้ใช้เป็นตัวจริง
สำหรับผู้ใช้ทั่วไปกระบวนการเหล่านี้คือการเอาโืทรศั พท์มือถือถ่ายรูป QR code บนหน้าจอเท่านั้น บนแอพ Google Authenticator ก็จะแสดงตัวเลขหกหลักออกมาทุกๆ 30 วินาทีให้เรากรอกบนเว็บเพื่อยืนยันตัวตนอยู่เสมอ
กระบวนการสร้างตัวเลขนี้กูเกิลไม่ได้สร้างขึ้นมาเอง แต่มีการสร้างมาตรฐานออกเป็นสองมาตรฐาน เรียกว่า HOTP (An HMAC-Based One-Time Password Algorithm), TOTP (Time-Based One-Time Password Algorithm)
HOTP ใช้แล้วทิ้ง
เมื่อแรกเริ่มออกมาตรฐานการสร้างรหัสผ่านแบบใช้ครั้ง เดียวแล้วทิ้ง เพื่อใช้ประกอบร่วมกับรหัสผ่านจากผู้ใช้นั้น กระบวนการออกแบบคือให้ผู้ใช้เก็บ ข้อความลับ (secret) เอาไว้ในอุปกรณ์ โดยอุปกรณ์ที่ว่านี้จะปล่อยตัวเลขออกมาใหม่ทุกครั้ง โดยตัวอุปกรณ์ยืนยันตัวตนจะนับจำนวนครั้งที่ผู้ใช้ และใช้ค่าจำนวนครั้งนั้นไปคำนวณค่ายืนยัน (Message Authentication Code - MAC) เพื่อใช้ยืนยันว่าผู้ใช้มีอุปกรณ์ที่เก็บความลับไว้จ ริง
ความได้เปรียบของ HOTP คืออุปกรณ์เองไม่ต้องการพลังงานในการทำงานใดๆ ทั้งสิ้นในขณะที่ไม่ได้ทำงาน ตัวอย่างสำคัญคือ YubiKey (ในภาพ) ที่จะทำงานเหมือนคีย์บอร์ดทุกครั้งที่ผู้ใช้แตะลงไปบ นปุ่มสัมผัส แต่ตัวเลขที่พิมพ์ออกมานั้นจะต่างไปทุกครั้ง เพราะตัวกุญแจจำได้ว่าตัวเองปล่อยรหัสผ่านออกไปแล้วก ี่ครั้ง
ชื่อ HOTP นั้นความสำคัญอยู่ที่กระบวนการ HMAC ที่เป็นการแฮชเพื่อส่งข้อมูลยืนยันโดยที่ไม่เปิดเผยว ่ากุญแจลับที่ใช้ยืนยันข้อความนั้นเป็นอะไร HMAC (สำหรับคนที่อ่านเรื่องการแฮชมาแล้ว อาจจะสงสัยว่าทำไมจึงนำกุญแจลับไปต่อกับเนื้อหาเอกสารตรงๆ ไม่ได้ ใน Stack Exchange มีพูดคุยกันในประเด็นนี้)
ข้อเสียของ HOTP คือเซิร์ฟเวอร์ต้องจำไว้เสมอ ว่าผู้ใช้ล็อกอินไปแล้วกี่ครั้ง ห้ามคลาดกันเอง ในกรณีที่ผู้ใช้กดดึงรหัสมาดูเล่นๆ ตัวเซิร์ฟเวอร์ก็ต้องตามไปหาว่ารหัสที่ส่งมานั้นเป็น ลำดับที่เท่าใด และต้องไม่ปล่อยให้ใช้งานรหัสผ่านลำดับที่ต่ำกว่านั้ น ในกรณีที่เซิร์ฟเวอร์มีหลายชุด หลายเครื่องทั่วโลก กระบวนการนี้อาจจะซับซ้อนขึ้น เพราะทุกเซิร์ฟเวอร์ต้องรู้ว่าผู้ใช้ใช้รหัสจากพวก
TOTP มาตามนัด
ความยุ่งยากของ TOTP สามารถแก้ได้ง่ายๆ ด้วยการใช้ เวลาปัจจุบัน มาสร้างรหัสผ่าน เซิร์ฟเวอร์ที่รู้ข้อความลับที่เหมือนกับอุปกรณ์ของผ ู้ใช้จะไม่ต้องรับรู้ว่าผู้ใช้ใช้รหัสผ่านไปแล้วกี่ค รั้ง แต่ต้องรู้เพียงเวลาปัจจุบันเท่านั้น ข้อจำกัดสำคัญคือตัวอุปกรณ์เองจะต้องรู้เวลาปัจจุบัน ด้วยเช่นกัน ทำให้ต้องมีแบตเตอรี่เลี้ยงนาฬิกาอยู่ตลอดเวลา และเวลานั้นยังต้องแม่นยำ
TOTP ในโทรศัพท์มือถือมีปัญหาน้อยมาก เพราะโทรศัพท์มือถือมีแบตเตอรี่ตลอดเวลาอยู่แล้ว ขณะเดียวกันนาฬิกาในโทรศัพท์มือถือก็แม่นยำเป็นอย่าง มากเพราะมีการตั้งนาฬิกาใหม่ทั้งจากเสาสัญญาณโทรศัพท ์มือถือและเซิร์ฟเวอร์เทียบเวลาผ่านอินเทอร์เน็ต รวมไปถึง GPS
Google Authenticator ทั้งหมดคือ URI
เมื่อกูเกิลออกแอพพลิเคชั่น Google Authenticator มานั้น กูเกิลรองรับทั้ง HOTP และ TOTP โดยองค์องค์ประกอบสำคัญของ Google Authenticator คือการกำหนดมาตรฐาน URI สำหรับการส่งความลับจากกูเกิลเข้ามายังโทรศัพท์มือถื อ เช่น
otpauth://totp/Example:alice@google.com?secret=JBSWY3DPEHPK3PXP&issuer=Exampleมาตรฐานนี้กำหนดส่ง ประเภทของ OTP, ชื่อบัญชี, ข้อความลับ, และชื่อหน่วยงาน ไปใน URI เดียวกัน ในการใช้งานจริงเรามักเห็น QR code จาก URI ก็จะได้ตามภาพ (สามารถเอาแอพ Google Authenticator สแกนได้จริง)
ข้อมูลอื่นๆ ที่จริงแล้วเป็นเพียงข้อมูลประกอบไว้แสดงให้ผู้ใช้เห ็นเวลาที่มีหลายๆ บัญชีในแอพเดียวกันเท่านั้น แต่ข้อความที่เป็นความลับจริงๆ คือ secret ที่มีค่าเป็น "JBSWY3DPEHPK3PXP" ค่านี้กูเกิลกำหนดให้เข้ารหัสแบบ base32 เอาไว้ ก่อนใช้งานจะต้องถอดรหัส base32 ก่อนจึงนำไปใช้เป็นกุญแจสำหรับ HMAC-SHA1 โดยค่าตัวอย่างนี้เมื่อถอดรหัสแล้วจะได้ค่าเป็น "Hello!\xde\xad\xbe\xef"
Google Authenticator ยังกำหนดให้รหัสเปลี่ยนไปทุกๆ 30 วินาที โดยใช้ค่าเวลา epoch (เวลาเป็นวินาทีย้อนกลับไปถึงวันที่ 1 มกราคม 1970) แล้วมาหารด้วย 30 เมื่อค่านี้เปลี่ยนไป ค่า OTP ก็จะเปลี่ยนด้วย สุดท้ายคือกำหนดให้แสดงรหัสผ่าน 6 หลัก ซึ่งน่าจะทนทานเพียงพอ เพราะแฮกเกอร์อาจะต้องเดารหัสผ่านหลายแสนครั้งเพื่อใ ห้ได้รหัสที่ถูกต้อง เซิร์ฟเวอร์โดยทั่วไปน่าจะทำให้การยิงทดสอบรหัสผ่านใ นระดับนี้ทำได้ยาก
RTC นาฬิกาแห่งคอมพิวเตอร์
คอมพิวเตอร์ของเราส่วนมากบนเมนบอร์ดมักมีแบตเตอรี่ขน าดเล็กๆ อยู่ แบตเตอรี่เหล่านี้มักทำหน้าที่จ่ายไฟเลี้ยงให้กับนาฬ ิกาในเครื่อง หรือที่เรียกชิปที่ทำหน้าที่นาฬิกาว่า real time clock (RTC) ชิป RTC มีหลายรุ่น ส่วนมากเป็นชิปที่ความแม่นยำค่อนข้างสูง สามารถทำงานได้นานนับปีโดยเวลาคลาดเคลื่อนเพียงเล็กน ้อย ในคอมพิวเตอร์เราแทบไม่เห็นความคลาดเคลื่อนนี้เพราะค อมพิวเตอร์เองก็มีระบบปรับเวลากับเซิร์ฟเวอร์เป็นระย ะ ชิป RTC ทำหน้าที่สำคัญคือการบอกเวลาทันทีที่บูตเครื่องขึ้นม า
ในคอมพิวเตอร์ขนาดเล็กที่ไม่มีชิป RTC ในตัวเช่น Raspberry Pi คอมพิวเตอร์จะไม่สามารถจำเวลาได้เมื่อปิดเครื่อง ทำให้เมื่อเปิดเครื่องขึ้นมาแล้วเวลาจะผิดพลาดเสมอ เราสามารถซื้อโมดูล RTC มาติดตั้งบน Raspberry Pi เพิ่มเติมเพื่อให้คอมพิวเตอร์จำเวลาได้แบบเดียวกับพี ซี
ในกรณีของบทความนี้จะใช้ชิป DS1307 ซึ่งเป็นที่นิยมในกลุ่มนักพัฒนาที่ใช้บอร์ด Arduino เพราะมีไลบรารีรองรับอยู่แล้วจำนวนมาก ไลบรารีที่สำคัญในการเชื่อมต่อกับ DS1307 ได้แก่ Wire, DS1307, และ Time
การเชื่อมต่อ DS1307 เข้ากับบอร์ด Arduino เพียงแต่ต่อสาย VCC, GND, SCL เข้าไปยัง D2, และ SDA ไปยัง D3 การใช้งานที่เหลือก็สามารถใช้งานผ่านไลบรารีได้โดยไม ่ต้องสนการเชื่อมต่อชั้นล่างๆ เช่น I2C
การตั้งเวลาใน RTC DS1307 สามารถตั้งจากตัวอย่างของไลบรารี SetTime ได้ทันที โดยตัวอย่างจะตั้งเวลาจากเวลาคอมไพล์และอัพโหลดซอฟต์ แวร์ลง Arduino ทำให้เวลาต่างจากเวลาจริงเพียงเล็กน้อยเท่านั้น
การอ่านค่าเวลา epoch จาก DS1307 สามารถอ่านผ่านฟังก์ชั่น now() ได้ทันที แต่เนื่องจากเวลาเป็นค่าของประเทศไทยที่เร็วกว่าเวลา UTC อยู่ 7 ชั่วโมง ดังนั้นจึงต้องลบเวลาออก 25200 วินาทีเพื่อจะได้เวลาที่ UTC
AVR-Crypto-Lib เข้ารหัสบน Arduino
ไลบรารีที่มีอยู่ใน Arduino มีอยู่มากมาย แต่ข่าวร้ายคือ Arduino ไม่มีไลบรารีสำหรับการเข้ารหัสโดยตรงทำให้จำเป็นต้อง พอร์ตไลบรารีมาด้วนตัวเอง สำหรับไลบรารีการคำนวณ HMAC-SHA1 นั้นมีผู้พัฒนาไว้อยู่แล้วในชื่อโครงการ AVR-Crypto-Lib ที่มีกระบวนการเข้ารหัสแบบต่างๆ มาให้พร้อมในตัวจำนวนมาก
เราสามารถแยกไลบรารีเฉพาะ HMAC-SHA1 มาใช้งานใน Arduino ได้เท่านั้นโดยแยกสี่ไฟล์ออกมาจากไลบรารี ได้แก่ sha1.c, sha1.h, hmac-sha1.c, และ hmac-sha1.h โดยทั้งสี่ไฟล์ต้องมีไฟล์ config.h, และ debug.h เราสามารถวางไฟล์เหล่านี้ว่างๆ เพื่อให้คอมไพล์ได้เลย ทั้งไลบรารี sha1 และ hmac-sha1 ควรสามารถคอมไพล์ได้จาก avr-gcc หากติดตั้งไว้ต่างหากในเครื่อง
ไลบรารีของ Arduino จะถูกจัดอยู่ในโฟลเดอร์โดยชื่อโฟลเดอร์จะต้องตรงกับช ื่อไฟล์ภายใน เราสามารถสร้างโฟลเดอร์ crypto และสร้างไฟล์ crypto.cpp ให้ include ไฟล์ hmac-sha1.c และ sha1.c และไฟล์ crypto.h ให้ include ไฟล์ hmac-sha1.h และ sha1.h ตามลำดับ จากนั้นจึงใส่ import library จาก Arduino IDE
เมื่อ import ได้สำเร็จแล้วสามารถทดสอบคอมไพล์โดยโค้ดดังต่อไปนี้
เราสามารถคำนวณ HMAC ของข้อมูลชุดหนึ่งๆ ด้วยการกำหนดกุญแจลงในฟังก์ชั่น hmac_sha1_init และตามด้วยข้อมูลที่ต้องการยืนยัน (ในกรณีของ Google Authenticator คือค่าเวลา epoch/30) ลงในฟังก์ชั่น hmac_sha1_lastBlock โดยเรียกข้อมูลยืนยันว่า บล็อคสุดท้าย (lastBlock) เพราะ HMAC นั้นรองรับการยืนยันข้อมูลขนาดใหญ่มากๆ ได้ โดยข้อมูลชุดสุดท้ายจะเป็นบล็อคสุดท้าย แต่บล็อคของ HMAC-SHA1 นั้นใหญ่ถึง 512 บิต และเวลา epoch นั้น มีขนาด 64 บิตทำให้ใช้เพียงบล็อคเดียว
การเชื่อมต่อกับคอมพิวเตอร์ว
หลังจากคำนวณค่าได้แล้ว ขั้นตอนสุดท้ายคือการเชื่อมต่อกับคอมพิวเตอร์ ในกรณีทั่วไปที่นิยมที่สุดคือการแสดงผลตัวเลขบนหน้าจ อขนาดเล็ก เพื่อให้ผู้ใช้ อ่านค่าและพิมพ์ลงในช่องขอยืนยัน กระบวนการนี้ไม่ยากนัก และ Arduino เองก็มีไลบรารี Arduino_GFX ให้ใช้งานกับจอภาพได้หลายประเภท แต่แต่ราคาร้อยกว่าบาทไปจนถึงราคาแพงๆ
แต่หากเรามี Arduino Leonardo (ตัวที่ Blognone แจกให้ Writer ทุกท่าน) ตัว Arduino จะสามารถจำลองตัวเองเป็นคีย์บอร์ดได้ ทำให้เราสามารถวางเคอเซอร์ไว้ที่ช่องพิมพ์รหัสยืนยัน , เสียบบอร์ด Arduino เข้า USB, แล้วตัวเลขจะพิมพ์ลงไปโดยตรงทันที
แนวทางนี้ทำให้เราสามารถสร้างโทเค็นฮาร์ดแวร์เพื่อยื นยันตัวตนขั้นตอนที่สองโดยโดยต้องการเพียงบอร์ด Arduino Leonardo และโมดูล RTC เท่านั้น
แนวทางการพัฒนาต่แ
ในโลกความเป็นจริงแล้วการใช้บอร์ด Arduino เพื่อให้พนักงานพกพาเอาไว้สำหรับการยืนยันตัวคนขั้นต อนที่สองคนเป็นเรื่องไม่สมเหตุสมผลนัก เนื่องจากบอร์ดมีขนาดใหญ่และใช้งานได้ยาก การทำเป็น dongle ขนาดเล็กอาจจะต้องการฮาร์ดแวร์ที่มีขนาดเล็กลงเช่น ps3ukey ที่ผมเคยเขียนถึงในโครงงานการเปลี่ยนภาษาด้วย Caplock แต่การดัดแปลงเพื่อติดตั้งชิป RTC ลงไปอาจจะเป็นเรื่องยุ่งยากพอสมควร
นอกปัญหาขนาดแล้ว Arduino เองยังมีปัญหา bootloader ของตัวเองที่กินเวลาในการบูตช่วงหนึ่ง กระบวนการนี้ทำให้โมดูลทำงานได้ช้าลง หากสามารถพัฒนารอมที่ตัดการทำงานของ bootloader ไปได้โครงการก็จะพร้อมใช้งานจริงได้ดีขึ้น
แนวทางพัฒนาสุดท้ายคือการรักษาความลับของค่ากุญแจที่ โปรแกรมลงไปในตัวชิป AVR ก่อนการใช้งานจริง (โดยเฉพาะการใช้งานในวงกว้าง กับคนจำนวนมาก) ควรมีการศึกษาแนวทางป้องกันการอ่านค่ากุญแจกลับขึ้นม าเสียก่อน เพื่อให้มั่นใจได้ว่าโทเค็นนี้จะไม่สามารถทำสำเนาได้ จริง
In-Depth, Security
อ่านต่อ...