Jednorázová hesla s S/KEY

1. 8. 2011
Doba čtení: 6 minut

Sdílet

Jednorázová hesla zná dnes každý – nejčastěji potkáme při dvoufaktorové autentizaci, například v internetovém bankovnictví. Dříve se používala také jako ochrana před odposlechnutím hesla při nešifrovaném přenosu po síti. V článku si představíme jednu z implementací jednorázových hesel, využívající řetězec hashů.

I když se v dnešní době používají především šifrované protokoly, u kterých je riziko odposlechu hesla výrazně sníženo, nemusíme jednorázová hesla nutně zahodit do starého železa. Několik příkladů použití v současnosti zahrnuje:

  • Protokol FTP. I přesto, že byl dávno doplněn o šifrování, stále je na světe v provozu spousta serverů a klientů, kteří šifrované spojení nepodporují a z různých důvodů je není možné nahradit.
  • Neoveřitelná autenticita SSH serveru. Může nastat situace, kdy v cizím prostředí nejsme schopni ověřit otisk SSH klíče serveru. Jednorázové heslo zabrání útočníkovi v odchycení hesla, neochrání však před únosem SSH relace po úspěšné autentizaci.
  • Potenciálně kompromitované prostředí. Jste-li nuceni pracovat například z počítače v internetové kavárně, také si nemůžete být jisti, zda není vybaven třeba keyloggerem.

Systém jednorázových hesel S/KEY, který si v tomto článku představíme, vznikl v osmdesátých letech dvacátého století ve společnosti Bellcore a byl postupně standardizován v RFC dokumentech 1760, 1938 a 2289. Novější standardy používají místo názvu S/KEY název OTP, neboť S/KEY je ochrannou známkou společnosti Bellcore. Implementace novějšího protokolu se však stále jmenují S/KEY, zřejmě proto, aby bylo jasné, o jaký typ jednorázového hesla se jedná.

Lamportovo schéma

Systém S/KEY generuje jednorázová hesla pomocí tzv. Lamportova schématu. To je založeno na jednosměrnosti hashovacích funkcí, tedy nesnadnosti až nemožnosti získat původní zprávu z obsahu hashe.

Jednorázová hesla jsou tvořena v sadách. Každá sada začíná vygenerováním výzvy (challenge) serveru, což je krátký náhodný řetězec znaků společný pro celou sadu. Uživatel k výzvě přidá své tajné úvodní heslo a vypočítá hash. Tím získá jednorázové heslo s pořadovým číslem nula. Další hesla ze sady získá opakovaným aplikováním hashovací funkce na předchozí heslo, jak naznačuje následující obrázek:

Poslední jednorázové heslo ve vygenerovaném řetězu se uloží spolu s vygenerovanou výzvou do databáze hesel serveru. V tuto chvíli se uživatel může přihlásit předposledním heslem ze sady. Server pro ověření provede hash uživatelem zadaného hesla. Pokud se shoduje výsledek hashe s heslem uloženým v databázi, je uživatel úspěšně ověřen a do databáze si server uloží heslo, které uživatel právě použil. Tak se v řetězu hesel postupuje až k nultému heslu, po kterém je nutné vygenerovat novou sadu. Protože se postupuje proti směru hashovacích funkcí, je téměř nemožné z již použitých hesel odhadnout, jaké heslo bude následovat.

Vlastní hesla jsou v systému S/KEY reprezentována 64-bitovými čísly. Můžeme je zapsat jako šestnáct šestnáctkových číslic s libovolně vloženými mezerami. Protože opisování šestnáctkových číslic je poměrně nepohodlné a navíc náchylné k chybám, nabízí S/KEY i alternativní zápis. Definuje slovník 2048 jedno- až čtyřpísmenných anglických slov. Heslo se rozdělí na šest částí po jedenácti bitech (dva přebývající bity se použijí jako kontrolní součet) a každá část se namapuje na jedno slovo. Takže například místo čísla 8F3E 3C98 0B14 365A je možné psát jednorázové heslo ve tvaru GOSH TWIT LOW GAS VAN NU. Na velikosti písmen ani na počtu mezer mezi slovy nezáleží, slova však musí být oddělena aspoň jednou mezerou.

S/KEY na Gentoo (a OpenBSD)

Distribuce Gentoo podporuje S/KEY pomocí balíčku, který na něj byl portován z OpenBSD. Podpora je řešena dvojím způsobem, buď pomocí use-flagu skey, kdy je použití S/KEY zakompilováno přímo do programů požadujících autentizaci (namátkou OpenSSH, shadow a sudo) nebo prostřednictvím univerzálního PAM modulu pam_skey. Osobně jsem zkoušel jen druhou variantu. K instalaci stačí zadat:

# emerge pam_skey

PAM modul zprovozníme přidáním následujícího řádku na začátek souboru, definujícího pravidla pro službu, kde chceme jednorázová hesla zprovoznit. Zvolil jsem soubor /etc/pam.d/system-remote-login, protože jednorázová hesla nechci používat při místním přihlášení.

auth [success=done ignore=ignore auth_err=die default=bad] pam_skey.so

V tuto chvíli je všechno připraveno, jako uživatel nyní můžeme vytvořit sadu jednorázových hesel. Vzhledem k tomu, že budeme zadávat bězné uživatelské heslo i master heslo, je nutné tuto činnost provádět na důvěryhodném spojení.

uzivatel@stanice:$ skeyinit -t sha1
Password: {běžné uživatelské heslo}
[Adding uzivatel]
Reminder - Only use this method if you are directly connected
or have an encrypted channel.  If you are using telnet
or rlogin, exit with no password and use skeyinit -s.

Enter secret password:
Again secret password:

ID uzivatel skey is otp-sha1 99 st61600
Next login password: FAD SLUM LUST BUY SCAT FOLD

Výše uvedené heslo se uloží do databáze hesel jako naposledy použité heslo. Při příštím přihlášení, například pomocí SSH, se objeví následující výzva:

otp-sha1 98 st61600
S/Key response or password:

Na důvěryhodném počítači s nainstalovaným balíkem skey spustíme příkaz, uvedený na prvním řádku výzvy ( otp-sha1 je symlink na utilitku  skey):

$ otp-sha1 98 st61600
Reminder - Do not use this program while logged in via telnet or rlogin.
Enter secret password:
USE LESK ANA MEN SHOW VETO

Generování jednorázového hesla můžete klidně svěřit i svému hloupému mobilnímu telefonu, díky implementaci v J2ME, pro chytřejší telefony a počítače dobře poslouží i implementace v javascriptu:

Pro další použití hesla se výzva serveru drobně změní – místo čísla 98 se objeví 97. Až se číslo přiblíží k nule, bude třeba na bezpečném terminálu připravit novou sadu hesel nástrojem  skeyinit.

Vzhledem k tomu, že obsah výzvy je předvídatelný a neměnný, dokud nedojde k úspěšnému přihlášení, není problém přihlašovat se jednorázovým heslem i pomocí protokolů, které zobrazení výzvy uživateli nepodporují, jako například FTP. Jednoduše výzvu získáme jinou cestou, aniž bychom přihlášení dokončili. Výzvu pro příští přihlášení poskytne také utilitka  skeyinfo:

$ skeyinfo
Your next otp-sha1 97 st61600

S/KEY na Debianu

Distribuce Debian obsahuje poněkud odlišnou implementaci, zvanou OPIE. Nainstalujeme ji příkazem:

# apt-get install libpam-opie

Po instalaci je třeba nastavit PAM modul. Na začátek souboru /etc/pam.d/common-auth přidáme volání modulu pam_opie.so. Aby bylo možné odpovědět na výzvu i běžným UNIXovým heslem, přidáme modulu pam_unix.so argument try_first_pass. Soubor bude vypadat tedy takto:

auth    sufficient                    pam_opie.so
auth    [success=1 default=ignore]    pam_unix.so nullok_secure try_first_pass

Debian má ve výchozím nastavení SSH serveru zakázáno interaktivní přihlášení klávesnicí. Aby se při přihlašování pomocí SSH zobrazila výzva, je třeba v konfiguračním souboru /etc/ssh/sshd_config upravit:

ChallengeResponseAuthentication yes
PasswordAuthentication no

Vytvoření sady hesel je obdobné distribuci Gentoo, pouze místo skeyinit používáme utilitu opiepasswd. Drobně odlišné je výchozí chování, opiepasswd předpokládá použití nezabezpečeným kanálem, takže namísto hlavního hesla požaduje externí vygenerování a vložení prvního hesla (= hesla na konci hash řetězu) na základě vygenerované výzvy. Program skeyinit se také neptá na uživatelské heslo. Aby jej nebylo možné zneužít na opuštěném terminálu, vyžaduje při každé druhé a další inicializaci nejprve zadání jednorázového hesla ze staré sady:

ict ve školství 24

uzivatel@stanice:$ opiepasswd
Updating uzivatel:
You need the response from an OTP generator.
Old secret pass phrase:
        otp-md5 498 st9489 ext
        Response: BEG CAGE KNEW CORK MART MOVE
New secret pass phrase:
        otp-md5 499 st9490
        Response: DEAL SUCH FULL SKID LOY NED

ID uzivatel OTP key is 499 st9490
DEAL SUCH FULL SKID LOY NED

Závěrem

Představený systém jednorázových hesel má svá nejlepší léta za sebou. Proto mně potěšilo, že i v dnešní době je možné S/KEY na moderních distribucích nainstalovat a používat. Implementace generátoru hesel v Javascriptu a v J2ME pokrývají téměř celé spektrum mobilních telefonů na trhu, takže narozdíl od minulosti již není nutné předem generovat větší sérii hesel a následně tisknout na papír. V tom byla také slabina systému S/KEY – pokud útočník byť jen na okamžik zahlédl papír s vygenerovanými jednorázovými hesly, stačilo mu zapamatovat si poslední heslo na seznamu. Díky Lamportovu schématu si mohl všechna předchozí hesla vypočítat opakovaným aplikováním hashovací funkce na zapamatované heslo.

Existují i další varianty jednorázových hesel. Pro moderní chytré telefony může být poměrně zajímavý Google Authenticator, který dokáže mimo jiné generovat proměnnou sekvenci hesel každých 30sekund, podobně jako známé krabičky SecurID. Další možností je balík OTPW, který je zvláště vhodný pro vytištění jednorázových hesel na list papíru. O něm si napíšeme možná někdy příště.

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