Google Authenticator: bezpečněji s jednorázovými hesly

13. 2. 2012
Doba čtení: 8 minut

Sdílet

Krádeže identity jsou dnes na internetu běžnou záležitostí. Není proto divu, že se objevují stále nová řešení, jak zabezpečit elektronické účty pomocí dalších autentizačních faktorů. Jeden takový implementoval Google a nabídl i modul, pomocí kterého může autentizaci jednorázovým heslem provozovat každý.

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.

Google Authenticator pro Android

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í.

Deset jednorázových hesel pro případ nouze

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 he­sel.

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.

ict ve školství 24

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.

Autor článku

Ondřej Caletka vystudoval obor Telekomunikační technika na ČVUT a dnes pracuje ve vzdělávacím oddělení RIPE NCC, mezinárodní asociaci koordinující internetové sítě.