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