⏱️ Криптографія та протоколи RFC ✓ Аналіз стандартів IETF

Різниця між TOTP та HOTP: порівняння, принципи роботи та безпека

Мільйони розробників та інженерів із безпеки щодня вводять змінні 6-значні коди підтвердження, проте небагато хто розуміє витончений математичний механізм, прихований за цими цифрами. Від лічильників подій RFC 4226 (HOTP) 2005 року до дискретних часових кроків RFC 6238 (TOTP) 2011 року — цей посібник розбирає алгоритм динамічного усічення на рівні байтів, вразливість розсинхронізації лічильників, компенсацію часового дрейфу та причини тріумфу TOTP у сучасному веб-просторі.

2FA
Команда безпеки 2FA-Tool
Оновлено: Жовтень 2026
Час читання: ~14 хв (понад 2 600 слів)
RFC 6238 RFC 4226 Динамічне усічення
💡 Ключові криптографічні висновки (Коротко)
  • Фундаментальна відмінність у вхідних даних: HOTP обчислює геші на основі монотонно зростаючого лічильника C, тоді як TOTP замінює C на часовий інтервал епохи T (поточний Unix-час / 30).
  • Пряме успадкування: TOTP математично є спеціалізацією HOTP: TOTP(K, Time) = HOTP(K, T). Обидва алгоритми застосовують абсолютно ідентичну функцію динамічного усічення (Dynamic Truncation).
  • Вирішальний архітектурний фактор: HOTP зберігає стан (stateful) — сервери повинні блокувати записи та оновлювати значення лічильника на диску при кожній валідації. TOTP не має стану (stateless), що дозволяє сучасним хмарним мікросервісам перевіряти токени через розподілені балансувальники навантаження без централізованих операцій запису в базу даних.
01

Історичні витоки: від пропрієтарних апаратних токенів до відкритих веб-стандартів

На початку 2000-х років корпоративна двофакторна автентифікація повністю залежала від пропрієтарних апаратних брелоків, таких як RSA SecurID. Ці закриті та дорогі пристрої містили вбудовані кварцові резонатори, синхронізовані із пропрієтарними серверами підприємства. Якщо компанія бажала захистити тисячі співробітників, витрати на закупівлю апаратного забезпечення та ліцензії були колосальними.

Щоб звільнити галузь від монополії постачальників закритого обладнання, лідери індустрії створили консорціум OATH (Initiative for Open Authentication). Його метою була розробка відкритих та безоплатних стандартів IETF, які будь-який інженер міг би вільно досліджувати, впроваджувати та аудитувати:

📜 2005: RFC 4226 (HOTP)

HMAC-Based One-Time Password Algorithm. Створений для низькоспоживаючих мікроконтролерів із фізичною кнопкою. Натискання кнопки збільшує внутрішній лічильник і виводить 6-значний токен на LCD-екран.

📜 2011: RFC 6238 (TOTP)

Time-Based One-Time Password Algorithm. Розроблений під час стрімкого поширення смартфонів. Завдяки мережевій синхронізації часу через NTP та стільникові мережі TOTP повністю усунув проблему розбіжності стану апаратних кнопок.

02

Архітектура HOTP (RFC 4226) та байтова механіка динамічного усічення

Базове математичне визначення HOTP є напрочуд лаконічним:

HOTP(K, C) = Truncate(HMAC-SHA-1(K, C)) mod 10DigitCount

Розшифровка параметрів:

  • K: Спільний симетричний секретний ключ (зазвичай двійкова послідовність на 160 біт / 20 байтів, декодована з Base32).
  • C: 8-байтовий (64-бітний) цілочисельний лічильник у форматі Big-Endian.
  • HMAC-SHA-1: Криптографічний код автентифікації повідомлень із ключем, що продукує 20-байтовий (160-бітний) дайджест.

🔍 Як динамічне усічення (Dynamic Truncation, DT) перетворює 20 байтів на 6 цифр:

Дайджест HMAC-SHA1 містить 160 бітів (20 байтів). Виділення 6 рівномірних десяткових цифр потребує детермінованого, стійкого до колізій механізму вибору, визначеного в розділі 5.3 специфікації RFC 4226:

// Крок 1: Обчислення динамічного зміщення (Offset)
Offset = HS[19] & 0x0F
Береться останній байт (індекс 19) 20-байтового дайджесту. Маскування 0x0F виділяє 4 молодші біти, що дає ціле число суворо від 0 до 15 (від 0x0 до 0xF). Це гарантує, що наступне зчитування 4 байтів ніколи не вийде за межі 20-байтового буфера (оскільки 15 + 4 = 19).
// Крок 2: Видобування 4 послідовних байтів із маскуванням
P = ( (HS[Offset] & 0x7F) << 24 ) | ( (HS[Offset+1] & 0xFF) << 16 ) | ( (HS[Offset+2] & 0xFF) << 8 ) | ( HS[Offset+3] & 0xFF )
Зчитуються 4 байти, починаючи з позиції Offset. Маска 0x7F обнуляє старший знаковий біт, щоб уникнути неоднозначності знакових цілих чисел на різних архітектурах процесорів (забезпечуючи чисте додатне 31-бітне ціле число).
// Крок 3: Арифметика за модулем для отримання фінальних цифр
OTP = P mod 106 = P mod 1000000
Застосування операції взяття за модулем 1 000 000 виділяє останні 6 десяткових цифр, доповнюючи результат провідними нулями за потреби (наприклад, 748 перетворюється на «000748»).
🧪 Конкретний тестовий вектор із Додатка D до RFC 4226:

Припустимо, секретний ключ — це ASCII-рядок "12345678901234567890", а значення лічильника C = 0. Отриманий дайджест HMAC-SHA1 у шістнадцятковому форматі:

cc 93 cf 18 50 8d 94 93 4c 64 b6 6d 8b fb 87 fb 23 cb 4b 71

1. Останній байт — 0x71. 0x71 & 0x0F = 0x01, отже Offset = 1.
2. Байти з 1-го по 4-й: 93 cf 18 50. Обнулення старшого біта дає 0x13cf1850, що в десятковій системі дорівнює 332 339 280.
3. 332339280 mod 1000000 = 339280. Отриманий 6-значний OTP — 339280!

03

Еволюція TOTP (RFC 6238): магія часових кроків

HOTP вимагав постійної синхронізації лічильника між клієнтом і сервером. У програмних додатках підрахунок натискань або спроб неминуче породжував людські та технічні помилки.

Стандарт RFC 6238 замінив подієвий лічильник C на дискретний часовий крок T, що обчислюється безпосередньо з системного годинника Unix-епохи:

T = ⌊ (CurrentUnixTime - T0) / X ⌋
  • CurrentUnixTime: Кількість секунд, що минули з 1970-01-01 00:00:00 UTC.
  • T0: Початкова точка відліку епохи (за замовчуванням дорівнює 0 в усіх сучасних системах).
  • X (Time Step Window): Стандартна рекомендована тривалість вікна — 30 секунд.
  • Функція округлення донизу ⌊ ⌋: Для будь-якої часової позначки всередині 30-секундного вікна значення T залишається незмінним. Наприклад, між 1728211200 та 1728211229 секундами епохи T обчислюється в абсолютно однакове 64-бітне ціле число.

Двійкова серіалізація: Після обчислення значення T упаковується у 8-байтовий буфер у форматі Big-Endian (ідентичний за структурою пам'яті до лічильника C в HOTP). Відповідно, уніфікована формула спрощується до:
TOTP(K, Time) = HOTP(K, T) Ця математична витонченість пояснює, чому додатки-автентифікатори синхронно змінюють коди кожні 30 секунд без потреби зберігати спільний стан у базі даних.

Підтримка SHA-256 та SHA-512 в RFC 6238: Якщо RFC 4226 строго визначав лише HMAC-SHA-1, то RFC 6238 розширив підтримку до HMAC-SHA-256 та HMAC-SHA-512. У разі SHA-256 (32-байтовий дайджест) зміщення зчитується з 31-го байта (HS[31] & 0x0F); у разі SHA-512 (64-байтовий дайджест) — з 63-го байта (HS[63] & 0x0F). Проте у 99,9% комерційних сервісів (Google, Microsoft, GitHub, AWS) SHA-1 залишається стандартом за замовчуванням задля повної зворотної сумісності з клієнтськими пристроями.
04

Детальна порівняльна матриця (HOTP проти TOTP)

Критерій порівняння HOTP (RFC 4226) TOTP (RFC 6238)
Вхідна змінна Лічильник подій C (монотонно зростає) Часовий крок T (30-секундне вікно Unix-епохи)
Термін дії токена Необмежений (дійсний до моменту наступного входу) Суворо 30 секунд (анулюється автоматично)
Архітектура сервера Зі збереженням стану (вимагає запису в БД при кожному вході) Без збереження стану (незалежна валідація за NTP)
Ризик повторного використання Середній (перехоплений токен дійсний, доки не використаний) Мінімальний (обмежений залишком секунд поточного вікна)
Основний тип збою Розсинхронізація лічильників (зайві натискання кнопки) Часовий дрейф (відхилення годинника на пристрої)
Підтримувані геші Виключно HMAC-SHA-1 HMAC-SHA-1, HMAC-SHA-256, HMAC-SHA-512
Рівень поширення Застарілі банківські брелоки, апаратні прохідні 99,9% сучасних інтернет-сервісів та автентифікаторів
05

Розсинхронізація та часовий дрейф: інженерні рішення

У реальних розподілених системах годинники клієнтів і серверів неминуче відхиляються. Криптографи заклали спеціальні механізми компенсації для підтримки надійності:

⚙️ Механізм захисту в HOTP: вікно випереджувальної перевірки (s)

Якщо користувач натиснув кнопку генератора 5 разів без відправки форми, лічильник клієнта досягає C+5, тоді як сервер залишається на C.
Специфікація RFC 4226 встановлює, що під час автентифікації сервер обчислює вікно випередження в діапазоні [C+1, C+s] (зазвичай s=20). Якщо знайдено збіг, сервер перестрибує вперед і негайно синхронізує значення лічильника C.

⏱️ Механізм захисту в TOTP: допуск часового дрейфу (вікно ±1)

Через мережеві затримки або неточний годинник смартфона (наприклад, відставання на 10 секунд) токени можуть надходити в сусідніх часових інтервалах.
Робочі сервери оцінюють масив із 3 вікон: [T-1, T, T+1], фактично розширюючи вікно прийому коду до 90 секунд.

Обов'язкове правило захисту від повторів (Anti-Replay): Щоб запобігти атакам повторного відтворення у 90-секундному інтервалі, сервери зобов'язані кешувати використані токени в оперативній пам'яті (наприклад, у Redis) щонайменше на 90 секунд, миттєво відхиляючи повторні спроби введення того ж коду.
🛡️ Порівняння рядків за сталий час (захист від атак за часом виконання / Timing Attacks):

Коли сервер перевіряє збіг введеного користувачем коду з обчисленим еталоном, стандартне порівняння рядків (на зразок userOtp === serverOtp) завершується на першому невідповідному символі. Зловмисник, що вимірює мікроскопічні коливання часу мережевої відповіді, здатний покроково підібрати всі цифри. Корпоративні бекенди застосовують алгоритми порівняння зі сталим часом виконання (наприклад, crypto.timingSafeEqual у Node.js або subtle.ConstantTimeCompare у Go), щоб повністю виключити витоки інформації через сторонні канали.

06

Чому TOTP підкорив сучасний інтернет

Вирішальна перемога TOTP над HOTP в інтернет-екосистемі була зумовлена трьома архітектурними перевагами:

☁️ Безсерверне масштабування

У розподілених мультирегіональних мікросервісах будь-який сервер із синхронізованим через NTP годинником може перевірити токен TOTP без звернення до центральної бази даних і без блокування записів.

📱 Синергія зі смартфонами

Смартфони постійно калібрують системний час через базові станції мобільного зв'язку та GPS, виключаючи розбіжність годинників без додаткових апаратних витрат.

🛡️ Вузьке 30-секундне вікно

Токени HOTP залишаються валідними нескінченно довго, доки їх не використають. Токени TOTP згорають через 30 секунд, автоматично знешкоджуючи скомпрометовані логи та перехоплені пакети.

🧮 Чистий рушій RFC 6238 на стороні клієнта

Спробуйте обчислення TOTP у реальному часі на 2FA-Tool

Подивіться, як секретний рядок Base32 перетворюється на динамічні 6-значні коди через динамічне усічення HMAC-SHA1. На 100% офлайн у вашому браузері.

Відкрити онлайн-генератор