Przejdź do treści
Cyberbezpieczeństwo

OTP, HOTP i TOTP: jak działają hasła jednorazowe i czym się różnią

HOTP generuje kody z licznika, TOTP z aktualnego czasu. Zobacz, jak działają hasła jednorazowe OTP według RFC 4226 i 6238, gdzie się je stosuje i jakie mają wady.

CZCzarek ZawolskiAktualizacja: 8 min czytania
Ilustracja haseł jednorazowych generowanych w aplikacji uwierzytelniającej

W skrócie

  • OTP (One-Time Password) to hasło jednorazowe — ważne dla jednego logowania lub transakcji, więc jego przechwycenie po użyciu nic nie daje.
  • HOTP (RFC 4226) liczy kod z tajnego klucza i licznika zwiększanego przy każdym użyciu; kod jest ważny, dopóki nie zostanie użyty.
  • TOTP (RFC 6238) to HOTP, w którym licznik zastąpiono czasem — domyślnie nowy kod co 30 sekund. Tak działają Google Authenticator i podobne aplikacje.
  • Kody OTP chronią przed wyciekiem haseł, ale nie przed phishingiem w czasie rzeczywistym. Odporne na phishing są dopiero klucze FIDO2 i passkeys.
  • Kody SMS to też OTP, ale najsłabsze: są podatne na przejęcie karty SIM i przekierowanie wiadomości.
Spis treści

HOTP i TOTP to dwa standardowe algorytmy generowania haseł jednorazowych (OTP). HOTP (HMAC-based One-Time Password, RFC 4226) liczy kod z tajnego klucza i licznika zwiększanego przy każdym użyciu, a TOTP (Time-based One-Time Password, RFC 6238) zastępuje licznik aktualnym czasem, dzięki czemu kod zmienia się sam — zwykle co 30 sekund. Na TOTP opierają się aplikacje takie jak Google Authenticator, Microsoft Authenticator czy Aegis.

W tym poradniku wyjaśniamy, czym jest hasło jednorazowe, jak dokładnie działają HOTP i TOTP (z kodem w Pythonie), czym się różnią i na co uważać, korzystając z nich w praktyce.

Co to jest OTP (One-Time Password)

Hasło jednorazowe (OTP, one-time password) to hasło ważne tylko dla jednego logowania lub jednej transakcji. Nawet jeśli ktoś je podejrzy lub przechwyci po użyciu, nie zaloguje się nim ponownie. Dlatego OTP stosuje się jako drugi składnik uwierzytelniania (2FA/MFA) obok zwykłego hasła — atakujący, który zdobył hasło z wycieku albo metodą password spraying, nadal nie ma kodu.

Hasła jednorazowe mogą powstawać na kilka sposobów:

SposóbJak działaPrzykłady
Lista lub karta kodówserwer i użytkownik mają tę samą listę jednorazowych kodówdawne bankowe karty kodów, kody zapasowe 2FA
Kod wysyłany kanałem pobocznymserwer losuje kod i wysyła go SMS-em lub e-mailemkody SMS do logowania i autoryzacji przelewów
Łańcuch skrótówkolejne hasła to kolejne wartości funkcji skrótu, używane od końcaS/KEY (RFC 1760), schemat Lamporta
Algorytm z licznikiemkod liczony z klucza i licznika zdarzeńHOTP, tokeny sprzętowe z przyciskiem
Algorytm z czasemkod liczony z klucza i aktualnego czasuTOTP, aplikacje uwierzytelniające

W bankowości elektronicznej kody jednorazowe służą także do autoryzacji operacji, np. przelewów. Od wejścia w życie wymogów silnego uwierzytelniania klienta (SCA) z dyrektywy PSD2 banki coraz częściej zastępują kody SMS potwierdzeniem w aplikacji mobilnej, ale SMS-y nadal są w użyciu.

Jak działa HOTP krok po kroku

HOTP opisano w RFC 4226 (2005). Serwer i urządzenie użytkownika (token lub aplikacja) dzielą dwie rzeczy: tajny klucz K oraz licznik C. Kod powstaje tak:

  1. Licznik C zapisuje się jako 8-bajtową liczbę.
  2. Oblicza się HMAC-SHA-1(K, C) — 20-bajtowy skrót z kluczem. Więcej o tym, czym są takie skróty, przeczytasz w tekście o funkcji skrótu kryptograficznego.
  3. Dynamiczne obcięcie (dynamic truncation): ostatnie 4 bity skrótu wskazują przesunięcie, od którego bierze się 4 bajty, a najstarszy bit się zeruje.
  4. Wynik dzieli się modulo 10^d, gdzie d to liczba cyfr (zwykle 6, czasem 8).
  5. Po każdym wygenerowaniu kodu licznik rośnie o 1.

Serwer wykonuje te same obliczenia. Ponieważ użytkownik mógł nacisnąć przycisk tokena kilka razy bez logowania, serwer sprawdza nie tylko bieżącą wartość licznika, ale też kilka kolejnych (okno synchronizacji). Po udanym logowaniu przestawia swój licznik na wartość z tokena.

Słabości HOTP

  • Kod nie wygasa sam. Jeśli ktoś zobaczy kod, który nie został jeszcze użyty, może z niego skorzystać nawet po wielu godzinach.
  • Licznik może się rozsynchronizować, gdy użytkownik wygeneruje więcej kodów, niż obejmuje okno serwera — wtedy potrzebna jest resynchronizacja.
  • 6 cyfr to tylko milion kombinacji, więc serwer musi ograniczać liczbę błędnych prób (RFC 4226 wprost to zaleca).

HOTP nadal występuje w tokenach sprzętowych bez zegara, np. w niektórych kluczach YubiKey w trybie OATH-HOTP, i tam, gdzie urządzenie nie ma wiarygodnego źródła czasu.

Jak działa TOTP

TOTP (RFC 6238, 2011) to HOTP, w którym licznik C zastąpiono numerem okna czasowego:

T = floor((aktualny czas Unix − T0) / X)
TOTP = HOTP(K, T)

Domyślnie T0 = 0 (początek epoki Unix), a X = 30 sekund. Telefon i serwer liczą T niezależnie, z własnych zegarów, więc nie muszą się ze sobą komunikować — dlatego aplikacja uwierzytelniająca działa bez internetu. Standard dopuszcza też HMAC-SHA-256 i HMAC-SHA-512, ale większość serwisów nadal używa SHA-1 i 6 cyfr. SHA-1 w konstrukcji HMAC nie jest tu słabym punktem: znane ataki na SHA-1 dotyczą kolizji, a nie HMAC.

Żeby tolerować drobne różnice zegarów i czas potrzebny na wpisanie kodu, serwery zwykle akceptują też kod z poprzedniego i następnego okna. Dobra implementacja zapamiętuje ostatnio użyty kod, by nie dało się go wykorzystać drugi raz w tym samym oknie.

Implementacja HOTP i TOTP w Pythonie

Cały algorytm mieści się w kilkunastu liniach i korzysta wyłącznie z biblioteki standardowej:

import base64, hashlib, hmac, struct, time

def hotp(key: bytes, counter: int, digits: int = 6) -> str:
    mac = hmac.new(key, struct.pack(">Q", counter), hashlib.sha1).digest()
    offset = mac[-1] & 0x0F                       # dynamiczne obcięcie (RFC 4226)
    code = struct.unpack(">I", mac[offset:offset + 4])[0] & 0x7FFFFFFF
    return str(code % 10 ** digits).zfill(digits)

def totp(key: bytes, step: int = 30, digits: int = 6) -> str:
    return hotp(key, int(time.time()) // step, digits)

klucz = b"12345678901234567890"   # klucz testowy z RFC 4226
print(hotp(klucz, 0), hotp(klucz, 1))   # 755224 287082

sekret = base64.b32decode("JBSWY3DPEHPK3PXP")
print(totp(sekret))

Wyniki 755224 i 287082 to wartości testowe z RFC 4226 — jeśli Twoja implementacja je zwraca, działa poprawnie. W prawdziwej aplikacji lepiej użyć sprawdzonej biblioteki, np. pyotp, która obsługuje też weryfikację z oknem czasowym.

Na Linuksie kody wygenerujesz narzędziem oathtool z pakietu oath-toolkit:

oathtool --totp -b JBSWY3DPEHPK3PXP          # TOTP z klucza w Base32
oathtool --hotp -c 0 3132333435363738393031323334353637383930   # HOTP, klucz w hex, licznik 0

Co zawiera kod QR przy włączaniu 2FA

Kod QR, który skanujesz przy włączaniu weryfikacji dwuetapowej, to po prostu adres w formacie otpauth://:

otpauth://totp/Serwis:jan@example.com?secret=JBSWY3DPEHPK3PXP&issuer=Serwis&algorithm=SHA1&digits=6&period=30

Najważniejszy jest parametr secret — tajny klucz zakodowany w Base32. Kto go zna, wygeneruje Twoje kody. Dlatego nie wysyłaj zrzutów ekranu kodu QR i nie zapisuj sekretu w notatkach.

HOTP a TOTP: porównanie

CechaHOTPTOTP
StandardRFC 4226RFC 6238
Zmienny czynniklicznik zdarzeńczas (okna po 30 s)
Ważność kodudo użycia lub do użycia nowszego kodujedno okno czasowe (plus zwykle ±1 okno tolerancji)
Wymaga zegara w urządzeniunietak, zsynchronizowanego
Typowy problemrozsynchronizowany licznikrozjechany zegar telefonu
Typowe zastosowanietokeny sprzętowe z przyciskiemaplikacje uwierzytelniające, menedżery haseł

W praktyce TOTP wyparł HOTP w usługach internetowych, bo kod wygasa sam i nie trzeba pilnować licznika. HOTP ma sens tam, gdzie urządzenie nie ma zegara.

Jak włączyć i bezpiecznie używać kodów TOTP

  1. Zainstaluj aplikację uwierzytelniającą: Google Authenticator, Microsoft Authenticator, Aegis (Android, open source), 2FAS albo Ente Auth. Kody TOTP obsługuje też wiele menedżerów haseł.
  2. W ustawieniach bezpieczeństwa serwisu wybierz weryfikację dwuetapową przez aplikację uwierzytelniającą.
  3. Zeskanuj kod QR i wpisz wygenerowany kod, aby potwierdzić konfigurację.
  4. Zapisz kody zapasowe (recovery codes) w bezpiecznym miejscu — offline lub w menedżerze haseł.
  5. Włącz kopię zapasową lub synchronizację w aplikacji uwierzytelniającej, jeśli ją oferuje, i zabezpiecz ją silnym hasłem.

Uwaga: Zgubienie telefonu bez kopii zapasowej kodów i bez kodów odzyskiwania często oznacza długą procedurę odzyskiwania konta albo jego utratę. Zabezpiecz kody zapasowe, zanim będą potrzebne.

Jeśli kody przestają działać, w pierwszej kolejności sprawdź zegar telefonu: w Androidzie Ustawienia → System → Data i godzina → Ustaw godzinę automatycznie, w iOS Ustawienia → Ogólne → Data i czas → Ustaw automatycznie. Różnica nawet kilkudziesięciu sekund wystarczy, by serwer odrzucał kody.

Ograniczenia haseł jednorazowych: SMS, phishing i co dalej

Kody OTP skutecznie chronią przed użyciem hasła wykradzionego z wycieku bazy. Nie chronią jednak przed wszystkim:

  • Phishing w czasie rzeczywistym. Fałszywa strona logowania działająca jako pośrednik (atak typu adversary-in-the-middle) przekazuje Twoje hasło i kod do prawdziwego serwisu w ciągu kilku sekund. Kod jest poprawny, więc atakujący loguje się i przejmuje sesję. Podobnie działa wyłudzanie przez fałszywe sieci Wi-Fi, opisane w tekście o Evil Twin phishing.
  • Kody SMS. Są wygodne, ale najsłabsze: przestępca może wyrobić duplikat karty SIM (SIM swapping), a wiadomości bywają przechwytywane lub przekierowywane. Jeśli serwis daje wybór, wybierz aplikację zamiast SMS-a.
  • Kradzież sekretu. Złośliwe oprogramowanie na telefonie albo wyciek bazy sekretów po stronie serwisu pozwala generować prawidłowe kody.
  • Socjotechnika. Nikt z banku ani serwisu nie poprosi Cię o podanie kodu przez telefon. Jeśli ktoś o to prosi, to oszustwo — więcej o takich metodach w artykule o najpopularniejszych sposobach kradzieży haseł.

Odporne na phishing są dopiero metody oparte na kryptografii klucza publicznego powiązanej z domeną: klucze sprzętowe FIDO2 i passkeys. Przeglądarka nie poda poświadczeń stronie o innej domenie, więc fałszywa strona niczego nie przechwyci. Szczegóły znajdziesz w tekście o tym, jak działa FIDO2.

Hasła jednorazowe w sieciach firmowych i dostępie gościnnym

OTP stosuje się nie tylko w serwisach internetowych. W firmach kody TOTP lub HOTP są często drugim składnikiem przy logowaniu do VPN, pulpitu zdalnego czy systemów administracyjnych — zwykle przez serwer RADIUS zintegrowany z systemem MFA. Systemy kontroli dostępu do sieci (NAC) z portalem przechwytującym (captive portal) potrafią z kolei wysyłać gościom jednorazowe hasła do Wi-Fi SMS-em lub e-mailem, dzięki czemu każdy dostęp jest przypisany do konkretnej osoby i wygasa po określonym czasie.

Którą metodę wybrać

  • Konto prywatne (poczta, media społecznościowe, sklep): passkey lub klucz FIDO2, jeśli serwis je obsługuje; w drugiej kolejności aplikacja TOTP; SMS tylko wtedy, gdy nie ma innej opcji.
  • Bank: potwierdzenia w oficjalnej aplikacji mobilnej banku; kody SMS czytaj w całości, bo zawierają kwotę i numer rachunku odbiorcy.
  • Firma: TOTP lub powiadomienia push z dopasowaniem numeru jako minimum, a dla administratorów i kont uprzywilejowanych — klucze FIDO2.
  • Tokeny sprzętowe bez zegara: HOTP, z ograniczeniem liczby prób i rozsądnym oknem synchronizacji.

Niezależnie od metody drugi składnik ma sens tylko w połączeniu z silnym, unikalnym hasłem. Jak je stworzyć i zapamiętać, wyjaśniamy w poradniku o bezpiecznych hasłach.

Najczęściej zadawane pytania

Co to jest HOTP?

HOTP (HMAC-based One-Time Password) to algorytm haseł jednorazowych opisany w RFC 4226. Kod powstaje z funkcji HMAC-SHA-1 obliczonej z tajnego klucza i licznika, który zwiększa się przy każdym wygenerowaniu kodu, a następnie jest skracany do 6–8 cyfr.

Czym różni się HOTP od TOTP?

HOTP używa licznika zdarzeń, więc kod jest ważny, dopóki nie zostanie użyty lub nie pojawi się nowszy. TOTP zamiast licznika używa czasu podzielonego na okna, zwykle 30-sekundowe, więc kod wygasa sam, nawet jeśli nikt go nie wpisał.

Czy TOTP jest bezpieczniejsze od HOTP?

Zwykle tak, bo przechwycony, ale niewykorzystany kod TOTP traci ważność po kilkudziesięciu sekundach, a kod HOTP może pozostać ważny długo. Oba algorytmy są tak samo podatne na phishing i kradzież tajnego klucza.

Czy aplikacja do kodów TOTP potrzebuje internetu?

Nie. Kody liczone są lokalnie z zapisanego klucza i zegara telefonu. Internet jest potrzebny tylko do ewentualnej synchronizacji kopii zapasowej, a ważne jest, by zegar urządzenia był ustawiony automatycznie.

Co zrobić, gdy kody z aplikacji uwierzytelniającej nie działają?

Najczęściej przyczyną jest rozjechany zegar telefonu. Włącz automatyczną datę i godzinę w ustawieniach systemu. Jeśli to nie pomaga, użyj kodów zapasowych i ponownie skonfiguruj 2FA w serwisie.

CZ

Autor

Czarek Zawolski

Założyciel i redaktor XAD.pl. Pisze o sieciach, bezpieczeństwie IT, administracji systemami Windows i Linux oraz o sprzęcie, który sprawia ludziom problemy na co dzień.