Před necelým rokem Google zpřístupnil uživatelům možnost dvoufázové autentizace účtů. Kromě uživatelského jména a hesla je potřeba zadat i číselné heslo. To se dozvíte buď prostřednictvím SMS zprávy na mobilní telefon, nebo si jej můžete vygenerovat pomocí aplikace Google Authenticator, dostupné pro nejrozšířenější platformy chytrých mobilních telefonů. Použití jednorázových hesel v krátkosti předvádí oficiální video.
Jak to funguje
Google se nevydal cestou (znovu)objevování již objeveného, místo toho přijal standard HOTP: An HMAC-Based One-Time Password Algorithm, popsaný v RFC 4226. Ten definuje způsob, jakým vypočítat každé jednorázové heslo z tajného klíče (K)
a počítadla (C)
, které se zvýší o jedničku při každém požadavku na nové heslo:
HOTP(K,C) = Truncate(HMAC-SHA-1(K,C))
Aniž bychom podrobně zkoumali detaily, můžeme prohlásit, že použitý algoritmus HMAC-SHA-1 představuje záruku, že jednotlivá hesla nebudou odvoditelná jedno od druhého. Velmi náročné by také mělo být zpětné odvození tajného klíče z posloupnosti odposlechnutých hesel (které mohou putovat po síti v otevřené podobě bez rizika).
Google tento standard rozšířil o podporu časově proměnných hesel jednoduše tak, že místo čítače počtu použití hesla do funkce vstupuje aktuální čas, standardně zaokrouhlený na třicetisekundové úseky. Tak vzniklo TOTP – Time-based One-time Password Algorithm, popsané v RFC 6238. To tvoří základ dvoufázového ověření pro Google účet.
Po zadání jména a hesla chce Google ještě vygenerovaný kód
Na rozdíl od jiných systémů jednorázových hesel, například S/KEY, je zpracování HOTP a TOTP shodné na straně klienta i serveru. Server drží stejný tajný klíč, při autentizaci provádí stejné operace jako klient a následně porovnává shodu výsledku klienta a serveru. V případě TOTP je tedy vyžadováno, aby se systémový čas na obou stranách příliš nelišil. Konkrétně server akceptuje kromě aktuálního hesla také jedno nazpět a jedno dopředu. Při třicetisekundovém intervalu změny hesla to znamená, že problém nastane, když se hodiny budou lišit o více než minutu.
Přenos a skladování klíče
Při zavádění jednorázových hesel je nutné, aby se obě strany domluvily na společném tajném klíči. V případě Google to probíhá tak, že Google vygeneruje osmdesátibitový klíč, který je třeba přenést do mobilního telefonu. Pro maximální usnadnění je k tomuto přenosu „zneužit“ QR kód. Do něj je zakódována speciální URL, pro kterou je jako prohlížeč zaregistrován Google Authenticator. Vlastní klíč je uložený v kódování base-32:
otpauth://totp/Muj%20tajny%20ucet?secret=HesloVBase32Kodu
Celá bezpečnost systému jednorázových hesel závisí na bezpečnosti tajného klíče. Jakmile jej útočník získá, zbývá mu v případě HOTP uhodnout aktuální hodnotu čítače. To může udělat třeba tak, že odposlechne jedno legitimní přihlášení uživatele a najde odposlechnuté heslo v řadě vygenerovaných hesel. V případě TOTP má útočník pozici ještě jednodušší, ačkoli RFC připouští i jiné metody, prakticky se hodnota čítače vždy rovná UNIXovému času dělenému třiceti sekundami.
Je tedy potřeba se ptát, jak jsou tajné klíče chráněny proti odcizení. Odpověď je možná trochu překvapivá: Nijak zvlášť chráněny nejsou. V případě Google Authenticatoru pro Android jsou klíče uloženy v SQLite databázi, do které mají přístup přinejmenším všechny procesy s oprávněním roota:
# sqlite3 /data/data/com.google.android.apps.authenticator/databases/databases sqlite> .schema CREATE TABLE accounts (_id INTEGER PRIMARY KEY, email TEXT NOT NULL, secret TEXT NOT NULL, counter INTEGER DEFAULT 0, type INTEGER); CREATE TABLE android_metadata (locale TEXT); sqlite> select * from accounts; 1|Muj tajny ucet|HesloVBase32Kodu|0|0
Slabé zabezpečení tajného klíče by představovalo problém, pokud by jednorázová hesla byla používána samostatně. Při předpokládaném scénáři použití se ale jednorázové heslo zadává jako doplněk navíc k běžnému heslu, takže i slabě zabezpečený klíč přináší výrazné zvýšení bezpečnosti systému jako celku.
Jednorázová záložní hesla
Pro případ, kdy zařízení generující jednorázová hesla není dostupné, je ztraceno nebo vybito, nabízí Google alternativu v podobě seznamu hesel pro jednorázové použití. Tato hesla nemají nic společného s algoritmem HOTP/TOTP a způsob jejich získání a ověření je velmi triviální.
Jsou vygenerována zcela náhodně a jejich seznam si udržuje jak uživatel, tak i server. Dojde-li k použití hesla, server jej ze seznamu vymaže, takže jej není možné použít znovu. Blíží-li se počet nepoužitých hesel k nule, musí uživatel autenticky požádat o vygenerování nové sady jednorázových hesel.
PAM modul pro ověřování jednorázových hesel
Součástí projektu Google Authenticator je také serverová část, implementovaná jako modul pro PAM. Díky tomu je možné jednorázová hesla HOTP a TOTP jednoduše začlenit do přihlašovacích mechanizmů většiny unixových operačních systémů.
Instalace je v tomto případě poněkud složitější. Nejen, že nejsou k dispozici binární balíky, ale dokonce nejsou vydány ani stabilní balíky zdrojových textů. Je tedy potřeba kompilovat přímo verzi z verzovacího systému Merrcurial:
$ hg clone https://code.google.com/p/google-authenticator/ $ cd google-authenticator/libpam/ $ make $ sudo make install
Inicializace hesel
Po úspěšné instalaci v systému přibude jak zmíněná PAM knihovna pam_google_authenticator.so
, tak i program google-authenticator
určený pro inicializaci jednorázových hesel. Ten musí spustit každý uživatel, který chce svůj účet ochránit. Program vygeneruje tajný klíč a zeptá se na několik dalších voleb:
$ google-authenticator Do you want authentication tokens to be time-based (y/n) y https://www.google.com/chart?chs=200x200&chld=M|0&cht=qr&chl=otpauth://totp/Muj%2520tajny%2520ucet%3Fsecret%3DHesloVBase32Kodu Your new secret key is: HesloVBase32Kodu Your verification code is 873003 Your emergency scratch codes are: 38452395 16741806 16012283 26021166 40158101 Do you want me to update your "/home/user/.google_authenticator" file (y/n) y Do you want to disallow multiple uses of the same authentication token? This restricts you to one login about every 30s, but it increases your chances to notice or even prevent man-in-the-middle attacks (y/n) y By default, tokens are good for 30 seconds and in order to compensate for possible time-skew between the client and the server, we allow an extra token before and after the current time. If you experience problems with poor time synchronization, you can increase the window from its default size of 1:30min to about 4min. Do you want to do so (y/n) n If the computer that you are logging into isn't hardened against brute-force login attempts, you can enable rate-limiting for the authentication module. By default, this limits attackers to no more than 3 login attempts every 30s. Do you want to enable rate-limiting (y/n) y
Uvedený URL obsahuje inicializační QR kód, vygenerovaný pomocí Google Chart API. I když je použit protokol HTTPS, stále je vhodné zvážit prozrazení tajného klíče online službě. Lepší je opsat klíč ručně, nebo použít nějaký offline generátor QR kódu. Je-li za běhu programu k dispozici knihovna qrencode, získáme QR kód přímo v terminálu:
Po zodpovězení všech otázek je v domácím adresáři uživatele vygenerován řídicí soubor. Jeho práva jsou nastavena tak, aby jej mohl číst jen uživatel. Soubor je textový a obsahuje postupně tajný klíč, volby a záložní jednorázová hesla:
$ cat ~/.google_authenticator HesloVBase32Kodu " RATE_LIMIT 3 30 " DISALLOW_REUSE " TOTP_AUTH 38452395 16741806 16012283 26021166 40158101
Nastavení PAM
Zařazení PAM modulu je možné několika způsoby. Tím nejběžnějším je samostatné zadání ověřovacího kódu po přihlášení běžným heslem. V Gentoo toho dosáhneme následujícím nastavením v souboru /etc/pam.d/system-auth
:
auth required pam_env.so auth required pam_unix.so auth required pam_google_authenticator.so nullok auth optional pam_permit.so
Volba nullok
byla do Google Authenticatoru přidána teprve nedávno a představuje jakousi opt-in alternativu, kde jednorázová hesla používá jen ten uživatel, který si již vygeneroval řídicí soubor. Pokud pro daného uživatele řídicí soubor neexistuje, modul v tichosti skončí úspěchem a umožní tak přihlášení i bez ověřovacího kódu. Bez této volby je přihlášení uživatelů bez řídicího souboru znemožněno. Výzva interaktivního terminálu při tomto způsobu přihlašování bude vypadat takto:
Password: {uživatel zadá heslo} Verification code: {uživatel zadá jednorázový ověřovací kód}
Nevýhodou tohoto přístupu je nekompatibilita s aplikacemi, které nepočítají s tím, že je k přihlášení potřeba zadat víc hesel. Typickým příkladem jsou grafické přihlašovací manažery. Pro takové případy je možné pořadí modulů obrátit a použít volbu forward_pass
:
auth required pam_env.so auth required pam_google_authenticator.so nullok forward_pass auth required pam_unix.so try_first_pass auth optional pam_permit.so
Při této konfiguraci se na heslo nejprve ptá Google Authenticator. Ten je schopen přijmout zároveň uživatelské heslo a ověřovací kód. Pokud na konci zadaného řetězce objeví platný ověřovací kód, modul jej odřízne a pošle dál pouze část hesla před ním. Další modul v této části najde unixové heslo uživatele a při úspěšném ověření jej rovnou přihlásí. Drobný problém nastane, pokud se uživatel splete a kontrolní kód nesouhlasí:
Password & verification code: <-- ptá se pam_google_authenticator.so, uživatel zadá špatný kód Password: <-- ptá se pam_unix.so, protože pam_google_authenticator.so selhal a heslo nepředal
Na druhou výzvu v tomto případě nemá smysl cokoli vyplňovat, ani správné heslo nemá šanci projít.
Závěr
Systém jednorázových hesel, který používá Google Authenticator, je ve srovnání s jinými systémy jednorázových hesel velmi jednoduchý a i poměrně zranitelný. Tajný klíč je bez většího zabezpečení uložen jak v klientském zařízení, tak na straně serveru.
Na druhou stranu nejspíše jednoduchost může standardům HOTP a TOTP pomoci stát se univerzálním autentizačním nástrojem. Že se to daří, dokazuje například v nedávný zápisek na blogu sdružení CZ.NIC s návodem, jak se pomocí Google Authenticatoru přihlašovat k informačnímu systému datových schránek.