- ความแตกต่างพื้นฐานของอินพุต: HOTP คำนวณแฮชจาก ตัวนับที่เพิ่มขึ้นเรื่อยๆ C (Monotonically Increasing Counter) ในขณะที่ TOTP แทนที่ C ด้วย ช่วงเวลา Epoch T (CurrentUnixTime / 30)
- การสืบทอดโดยตรง: ในทางคณิตศาสตร์ TOTP คือกรณีพิเศษของ HOTP:
TOTP(K, Time) = HOTP(K, T)ทั้งสองอัลกอริทึมใช้ฟังก์ชัน Dynamic Truncation เดียวกันทุกประการ - ปัจจัยชี้ขาดเชิงสถาปัตยกรรม: HOTP เป็นแบบมีสถานะ (Stateful) เซิร์ฟเวอร์ต้องล็อกและบันทึกค่าตัวนับลงดิสก์ทุกครั้งที่ตรวจสอบสำเร็จ แต่ TOTP เป็นแบบไร้สถานะ (Stateless) ทำให้ไมโครเซอร์วิสบนคลาวด์สามารถตรวจสอบรหัสผ่านโหลดบาลานซ์ได้โดยไม่ต้องแย่งกันเขียนฐานข้อมูล
จุดกำเนิด: จากฮาร์ดแวร์โทเค็นเฉพาะสู่มาตรฐานเว็บเปิด
ในช่วงต้นทศวรรษ 2000 การยืนยันตัวตนสองขั้นตอนในระดับองค์กรถูกผูกขาดโดยฮาร์ดแวร์โทเค็นเฉพาะทาง เช่น พวงกุญแจ RSA SecurID อุปกรณ์เหล่านี้มีราคาแพงและมีคริสตัลควอตซ์ภายในที่ซิงค์เวลากับเซิร์ฟเวอร์เฉพาะของบริษัทผู้ผลิต หากองค์กรต้องการแจกโทเค็นความปลอดภัยให้กับพนักงานหลายพันคน ค่าจัดซื้อฮาร์ดแวร์และค่าลิขสิทธิ์จะมีมูลค่ามหาศาล
เพื่อปลดแอกระบบยืนยันตัวตนออกจากผู้ขายเฉพาะราย กลุ่มพันธมิตร OATH (Initiative for Open Authentication) จึงถูกก่อตั้งขึ้นโดยผู้นำในอุตสาหกรรม เพื่อสร้างมาตรฐานเปิดของ IETF ที่ไม่มีค่าลิขสิทธิ์ ซึ่งวิศวกรซอฟต์แวร์ทุกคนสามารถตรวจสอบ พัฒนา และใช้งานได้อย่างเสรี:
อัลกอริทึมรหัสผ่านใช้ครั้งเดียวตาม HMAC ออกแบบมาสำหรับไมโครคอนโทรลเลอร์พลังงานต่ำที่มีปุ่มกด เมื่อกดปุ่ม ตัวนับภายในจะเพิ่มขึ้น และแสดงรหัส 6 หลักบนหน้าจอ LCD
อัลกอริทึมรหัสผ่านใช้ครั้งเดียวตามเวลา ออกแบบขึ้นในยุคที่สมาร์ตโฟนเริ่มแพร่หลาย โดยอาศัยการซิงค์เวลากับเครือข่ายมือถือผ่าน NTP ทำให้ตัดปัญหาตัวนับไม่ตรงกันจากการกดปุ่มออกไปได้อย่างสิ้นเชิง
สถาปัตยกรรม HOTP (RFC 4226) & กลไก Dynamic Truncation ในระดับไบต์
คำจำกัดความทางคณิตศาสตร์หลักของ HOTP มีความกระชับและสง่างามอย่างยิ่ง:
รายละเอียดของตัวแปร:
K: คีย์ลับสมมาตรที่ใช้ร่วมกัน (มักเป็นข้อมูลไบนารี 160 บิต / 20 ไบต์ที่ถอดรหัสมาจาก Base32)C: ตัวนับจำนวนเต็มขนาด 8 ไบต์ (64 บิต) แบบ Big-EndianHMAC-SHA-1: ฟังก์ชัน Keyed-hash message authentication code ที่สร้างไดเจสต์ขนาด 20 ไบต์ (160 บิต)
🔍 กลไก Dynamic Truncation (DT) แปลงข้อมูล 20 ไบต์เป็นตัวเลข 6 หลักได้อย่างไร:
ไดเจสต์ HMAC-SHA1 มีความยาว 20 ไบต์ การดึงเลขฐานสิบ 6 หลักออกมาอย่างสม่ำเสมอและไม่เกิดการชนกัน ต้องใช้กลไกการเลือกแบบกำหนดได้แน่นอนตาม RFC 4226 หัวข้อ 5.3:
สมมุติว่าคีย์ลับคือสตริง ASCII "12345678901234567890" และตัวนับ C = 0 จะได้ผลลัพธ์ HMAC-SHA1 ในเลขฐานสิบหกดังนี้:
1. ไบต์สุดท้ายคือ 0x71 โดย 0x71 & 0x0F = 0x01 ดังนั้น Offset = 1
2. ไบต์ตำแหน่งที่ 1 ถึง 4 คือ: 93 cf 18 50 เมื่อเซ็ต MSB เป็น 0 จะได้ 0x13cf1850 ซึ่งแปลงเป็นฐานสิบได้ 332,339,280
3. 332339280 mod 1000000 = 339280 ดังนั้น รหัส OTP 6 หลักที่ได้คือ 339280!
วิวัฒนาการสู่ TOTP (RFC 6238): พลังของคาบเวลา (Time-Step Magic)
HOTP จำเป็นต้องซิงค์ตัวนับระหว่างเครื่องผู้ใช้กับเซิร์ฟเวอร์ แต่การนับจำนวนการกดปุ่มบนอุปกรณ์ซอฟต์แวร์มักเกิดความผิดพลาดจากการกระทำของมนุษย์ได้ง่าย
RFC 6238 จึงได้แทนที่ตัวนับ C ด้วย ช่วงเวลาไม่ต่อเนื่อง T ที่คำนวณจากนาฬิกา Unix Epoch โดยตรง:
- CurrentUnixTime: วินาทีที่ผ่านไปนับตั้งแต่วันที่ 1 มกราคม 1970 00:00:00 UTC
- T0: จุดอ้างอิงเริ่มต้นของเวลา (ในระบบปัจจุบันกำหนดให้เป็น 0 เสมอ)
- X (หน้าต่างคาบเวลา): ระยะเวลามาตรฐานที่แนะนำคือ 30 วินาที
- ฟังก์ชันปัดเศษลง ⌊ ⌋: ตลอดระยะเวลา 30 วินาทีใดๆ ค่า T จะมีค่าคงที่เสมอ เช่น ระหว่างวินาทีที่ 1728211200 ถึง 1728211229 ค่า T จะได้จำนวนเต็ม 64 บิตเดิมทุกประการ
การจัดเก็บในรูปแบบไบนารี: เมื่อคำนวณค่า T ได้แล้ว ระบบจะแปลง T เป็นไบต์บัฟเฟอร์ขนาด 8 ไบต์แบบ Big-Endian (โครงสร้างเดียวกับตัวนับ C ใน HOTP) ทำให้สูตรสรุปของ TOTP คือ:
TOTP(K, Time) = HOTP(K, T)
ความเรียบง่ายทางคณิตศาสตร์นี้เองที่ทำให้แอปยืนยันตัวตนสามารถหมุนเวียนรหัสได้พร้อมกับเซิร์ฟเวอร์ทุก 30 วินาที โดยไม่ต้องมีการส่งข้อมูลอัปเดตสถานะตัวนับหากันเลย
HS[31] & 0x0F) และใน SHA-512 (ไดเจสต์ 64 ไบต์) จะดึงจากไบต์ที่ 63 (HS[63] & 0x0F) อย่างไรก็ตาม ในเว็บไซต์เชิงพาณิชย์กว่า 99.9% (Google, Microsoft, GitHub, AWS) SHA-1 ยังคงเป็นมาตรฐานหลักเพื่อความเข้ากันได้กับแอปมือถือรุ่นเก่า
ตารางเปรียบเทียบเชิงลึกแบบเคียงข้างกัน (HOTP vs. TOTP)
| มิติการเปรียบเทียบ | HOTP (RFC 4226) | TOTP (RFC 6238) |
|---|---|---|
| ตัวแปรอินพุต | ตัวนับเหตุการณ์ C (เพิ่มขึ้นเรื่อยๆ) | ช่วงเวลา T (หน้าต่าง 30 วินาที Unix Epoch) |
| อายุขัยของรหัสผ่าน | ไม่จำกัดเวลา (ใช้ได้จนกว่าจะล็อกอินสำเร็จ) | 30 วินาทีเท่านั้น (หมดอายุโดยอัตโนมัติ) |
| สถาปัตยกรรมเซิร์ฟเวอร์ | Stateful (ต้องเขียนฐานข้อมูลล็อกตัวนับทุกครั้ง) | Stateless (ตรวจสอบได้อิสระผ่านเวลา NTP) |
| ความเสี่ยงจากการโจมตีแบบ Replay | ปานกลาง (รหัสที่ดักจับได้ใช้ได้จนกว่าเจ้าของจะล็อกอิน) | ต่ำมาก (รหัสใช้งานได้เฉพาะในวินาทีที่เหลือของรอบ) |
| ปัญหาหลักที่พบบ่อย | ตัวนับไม่ตรงกัน (จากการเผลอกดปุ่มเล่น) | นาฬิกาคลาดเคลื่อน (เวลาของโทรศัพท์ไม่ตรง) |
| ฟังก์ชันแฮชที่รองรับ | HMAC-SHA-1 เท่านั้น | HMAC-SHA-1, HMAC-SHA-256, HMAC-SHA-512 |
| การนำไปใช้ในปัจจุบัน | โทเค็นฮาร์ดแวร์ธนาคารรุ่นเก่า, ประตูดิจิทัล | 99.9% ของระบบยืนยันตัวตนบนเว็บสมัยใหม่ |
การแก้ปัญหา Desynchronization และ Time Drift เชิงวิศวกรรม
ในสภาพแวดล้อมโปรดักชันจริง ความล่าช้าของเครือข่ายและนาฬิกาที่ไม่ตรงกันย่อมเกิดขึ้นได้ นักวิทยาการรหัสลับจึงได้ออกแบบหน้าต่างชดเชยเพื่อรักษาความเสถียรของระบบ:
หากผู้ใช้กดปุ่มโทเค็นเล่นไป 5 ครั้งโดยไม่ได้ล็อกอิน ตัวนับฝั่งไคลเอนต์จะกลายเป็น C+5 ในขณะที่เซิร์ฟเวอร์ยังอยู่ที่ C
RFC 4226 จึงกำหนดให้เซิร์ฟเวอร์คำนวณรหัสล่วงหน้าครอบคลุมช่วง [C+1, C+s] (โดยทั่วไป s=20) หากพบรหัสที่ตรงกัน เซิร์ฟเวอร์จะกระโดดตัวนับไปที่จุดนั้นและซิงค์ข้อมูลให้ทันที
เนื่องจากความล่าช้าในการส่งผ่านเครือข่ายหรือเวลาของโทรศัพท์เดินช้าไปเล็กน้อย รหัสอาจมาถึงในช่วงเวลาถัดไป
เซิร์ฟเวอร์ในระบบจริงจะตรวจสอบรหัสล่วงหน้าและย้อนหลังครอบคลุม 3 หน้าต่างเวลา: [T-1, T, T+1] ซึ่งเทียบเท่ากับช่วงเวลายอมรับ 90 วินาที
เมื่อเซิร์ฟเวอร์ตรวจสอบว่ารหัสที่ผู้ใช้กรอกตรงกับรหัสที่คำนวณได้หรือไม่ การเปรียบเทียบสตริงแบบทั่วไป (เช่น userOtp === serverOtp) จะหยุดการทำงานทันทีที่เจอตัวอักษรตัวแรกที่ไม่ตรงกัน ผู้โจมตีที่จับเวลาการตอบสนองของเครือข่ายในระดับไมโครวินาทีอาจสามารถเดารหัสทีละหลักได้ (Timing Attack) แบ็กเอนด์ระดับองค์กรจึงต้องบังคับใช้ฟังก์ชันเปรียบเทียบแบบเวลาคงที่เสมอ (เช่น crypto.timingSafeEqual ใน Node.js)
ทำไม TOTP ถึงชนะใจนักพัฒนาและครองโลกอินเทอร์เน็ต
ชัยชนะอย่างเด็ดขาดของ TOTP เหนือ HOTP บนเว็บสมัยใหม่ขับเคลื่อนด้วยปัจจัยสำคัญ 3 ประการ:
ในระบบไมโครเซอร์วิสแบบหลาย Region เซิร์ฟเวอร์ทุกเครื่องที่ซิงค์เวลาผ่าน NTP สามารถตรวจสอบรหัส TOTP ได้ทันทีโดยไม่ต้องเชื่อมต่อหรือแย่งกันเขียนฐานข้อมูลส่วนกลาง
สมาร์ตโฟนจะปรับเวลาให้ตรงกับเสาสัญญาณมือถือและดาวเทียม GPS อยู่เสมอ ตัดปัญหาเรื่องเวลาคลาดเคลื่อนโดยไม่ต้องมีทีมช่างคอยดูแลฮาร์ดแวร์
รหัส HOTP ใช้ได้ตลอดไปจนกว่าจะล็อกอิน แต่รหัส TOTP หมดอายุใน 30 วินาที ช่วยลดความเสี่ยงจากการที่รหัสรั่วไหลหรือถูกดักจับผ่านเครือข่ายลงได้อย่างมาก
สัมผัสการคำนวณรหัส TOTP แบบเรียลไทม์ใน 2FA-Tool
ดูว่าคีย์ลับ Base32 ของคุณถูกแปลงเป็นรหัส 6 หลักได้อย่างไรผ่านการคำนวณ HMAC-SHA1 Dynamic Truncation ทำงานแบบออฟไลน์บนเบราว์เซอร์ของคุณ 100%
📚 คู่มือความปลอดภัยที่เกี่ยวข้อง
วิธีย้ายบัญชี 2FA ข้ามสมาร์ตโฟนผ่านการสแกน QR แบบออฟไลน์และ Cloud Sync
กฎการบังคับใช้ 2FA, การบันทึกรหัสกู้คืน, สิทธิ์คีย์ SSH และวิธีแก้บัญชีล็อก
วิธีกู้คืนสิทธิ์การเข้าถึงสำหรับ Google, Microsoft, Steam, Binance, Apple และ Discord