PkYubikey

Na předchozí článek, který vás seznámil s Yubikey, navazuji druhým textem, kterým už se pomalu blížíme k praktickým záležitostem: představuji vám knihovnu PkYubikey, kterou budu používat v dalších aplikacích (připraven mám FTP server, chystám se podívat na VNC, postupně třeba přijdou i další projekty). V tuto chvíli slouží hlavně dvěma účelům: předvést, jak jednoduché je implementovat podporu Yubikey do vašich aplikací, a provést vám základním nastavením, které budou používat všechny mé další implementace.

libYubikey

Knihovna PkYubikey je napsána v jazyce Pascal (konkrétně v implementaci Delphi, ale lze ji zkompilovat i FreePascalem) a tvoří ji několik částí. Jejím základem je libYubikey, což není nic jiného než přepis výrobcem podporované Cčkové knihovny libyubikey do Pascalu. Moje invence se v tomto případě omezila na to, že jsem všechny funkce umístil do jediného souboru a mírně jsem přepsal funkce pro převod mezi hexadecimálním, modhexovým a binárním vyjádřením dat – přišlo mi hloupé mít pro hex i modhex samostatné funkce, když se obě kódování liší jen v použité abecedě. Z hlediska publikovaných funkcí a vstupů i výstupů ovšem všechno zůstalo tak, jako v původním libyubikey.

Jaké funkce tedy libyubikey nabízí:

  • procedure YubikeyModhexEncode(Dest, Src: PChar; SrcSize: integer);
    procedure YubikeyModhexDecode(Dest, Src: PChar; DestSize: integer);
    procedure YubikeyHexEncode(Dest, Src: PChar; SrcSize: integer);
    procedure YubikeyHexDecode(Dest, Src: PChar; DestSize: integer);

    Funkce pro konverzi z hex resp. modhex řetězců do binární podoby a zpět. Fukce *Encode vezmou binární string (sekvenci bajtů) a převedou ho na ASCII string v příslušném kódování. Pokud bych například kódoval sekvenci bajtů 0x12, 0x56, 0x9a, 0xcd, výsledkem YubikeyHexEncode by byl řetězec '12569acd', výsledkem YubikeyModhexEncode pak 'bdghklrt'. *Decode funkce dělají opačný převod.

  • function YubikeyCRC16(Buffer: PChar; BufSize: integer): word;

    Funkce pro výpočet CRC16 kontrolního součtu zadaného binárního řetězce. Používá se pro ověření platnosti dat dekódovaných z Yubikeyovského hesla.

  • [pasca]procedure YubikeyAesDecrypt(State: PYubikeyToken; Key: PYubikeyKey);[/pascal]

    Implementace rozšifrování dat zašifrovaných algoritmem AES s 128bitovým klíčem. Jak jsem si ověřil, jde skutečně o standardní AES; můžete ho použít na definované testovací vektory a skutečně dostanete očekávaný výsledek. Je to také evidentní důvod, proč vlastně Yubikey používá právě tak dlouhá hesla, jako používá, a obsahuje taková data, jaká obsahuje: AES pracuje na blocích o délce 128 bitů (16 bajtů), a právě jen při téhle délce dat není třeba řešit ani padding (doplnění kratších dat na danou délku), ani šifrovací režimy.

  • procedure YubikeyParse(OTP: PYubikeyOTP; Key: PYubikeyKey; Parsed: PYubikeyToken);

    „Vysokoúrovňová“ funkce, jejímž účelem je převést jednorázové heslo do binární podoby (funkcí YubikeyModhexDecode) a následně ho dešifrovat (funkcí YubikeyAesDecrypt). Není mi úplně jasné, proč Yubico tohle označuje za vysokoúrovňovou funkci, když to nic jiného nedělá – dokonce ani ověření, že dešifrovaná data jsou správná (a tedy vstupní heslo i tajný AES klíč jsou platné).

uYubikey

uYubikey už je můj příspěvek do rodiny Yubikey knihoven. Využívá výše zmiňovanou libYubikey pro vytvoření tří funkcí, které už za vysokoúrovňové klidně jde označit:

  • function PKYubikeyRegisterOTP(Name: PChar; UID: PYubikeyUID; Key: PYubikeyKey; OtpCounter: Longint): Longint;

    Tato funkce je „inicializační“ – slouží k zaregistrování konkrétního Yubikey do systému. POtřebuje k tomu čtyři základní údaje:

    • Name: PChar je řetězec, kterým bude daný Yubikey nadále identifikován. Typicky obsahuje přihlašovací jméno uživatele, který daný Yubikey používá (tedy např. „pepak“). Slouží k tomu, aby se na daný Yubikey dalo odkazovat nějakým „lidsky srozumitelným“ názvem – a konec konců, skoro každá aplikace bude kromě hesla vyžadovat i jméno, tak proč ho nepoužít. Délka je libovolná a obsah také, s výhradou, že nesmí obsahovat binární nulu (znak s ASCII kódem 0) a bylo by lepší, kdyby neobsahovalo zpětné lomítko.
    • UID: PYubikeyUID je ukazatel na řetězec šesti bajtů, které tvoří privátní ID tokenu (nastavuje se v personalizační aplikaci pro Yubikey). Podle něj program pozná, že zadané heslo patří k uživatelskému jménu.
    • Key: PYubikeyKey je ukazatel na řetězec šestnácti bajtů, které jsou použity jako AES klíč.
    • OtpCounter: Longint je aktuální hodnota počitadla tokenu. Rozumná počáteční hodnota je nula.

    Registrační funkce udělá vlastně jedinou věc: do systémového registru do větve HKEY_LOCAL_MACHINE\Software\Pepak\Yubikey zapíše nový klíč Name (proto je vhodné, aby neobsahoval zpětné lomítko) a v něm založí záznamy pro ostatní tři parametry. Tyto záznamy nejsou nijak šifrovány, což může působit nebezpečně, ale vzhledem ke konstrukci tokenu nemám moc na výběr: Klíč a počitadlo potřebuji přesně v té podobě, v jaké je uživatel zadal, bez toho se vůbec nedá jednorázové heslo ověřit. UID by v zásadě mohlo být v podobě nějakého hashe, ale vzhledem k velmi malému prostoru možných UID (jen 6 bajtů, tedy 48 bitů) to nemá moc smysl – každý serioznější útočník by dokázal ve velmi krátké době prostě vyzkoušet všechny možnosti. Musel bych použít techniky z TrueCryptu a hash aplikovat mnohokrát po sobě (řádově tak milionkrát), abych vůbec dokázal UID ochránit. Což se zdá jako plýtvání s ohledem na fakt, že pokud už se útočník dostane k registru dotyčného serveru, dokáže nepochybně nahradit třeba i samotnou ověřovací knihovnu…

  • function PKYubikeyRegisterOTPhex(Name, UIDHex, KeyHex: PChar; OtpCounter: Longint): Longint;

    Tato funkce pracuje přesně stejně jako ta předchozí, jen očekává jinou podobu UID a klíče – zatímco výše šlo o binární stringy, zde jsou očekávány řetězce hexa znaků.

  • function PKYubikeyValidateOTP(Name, OTP: PChar): Longint;

    Tato funkce řeší veškerou autentizaci. Na vstupu očekává jméno tokenu (řetězec Name z funkcí výše) a jednorázové heslo dodané Yubikeyem, na výstupu vrátí buď nulu (autentizace proběhla v pořádku – jde o správný token a nedošlo k opakování hesla) nebo chybový kód. Všechny potřebné operace, včetně zabránění dvojího přístupu k jedněm datům, už si funkce ohlídá sama. Vy prostě zavoláte if PKYubikeyValidateOTP('pepak', '123456...') = 0 then ... a vůbec neřešíte, z čeho se to jednorázové heslo skládá a jak je zajištěno, že ho nikdo nebude moci opakovat – to všechno si zařídí tato funkce.

PkYubikeyDll.dll

Tato komponenta je vlastně to samé co uYubikey výše, ale v podobě DLL knihovny. Díky tomu jsou zmiňované tři funkce dostupné jakémukoliv programovacímu jazyku, který umí vytvářet programy pro Windows – stačí naimportovat DLL (k tomu má každý jazyk své prostředky) a začít používat jeho funkce. Reálné použití bude vidět ve FTP serveru, který popíšu v nejbližší budoucnosti – ten je psaný v jazyce C, nicméně používat DLL vytvořené v Delphi pro něj není nejmenší problém…

PkYubikey.exe

PkYubikey.exe se velmi podobá PkYubikeyDll.dll v tom, že jde vlastně o zasazení uYubikey do určitého interfacu. V tomto případě jde o utilitu, zpřístupňující funkce PKYubikeyRegisterOTPhex a PKYubikeyValidateOTP z příkazového řádku. Použití je v zásadě dvojí:

  1. Registrování Yubikey do systému. Nemusíte nic vědět o tom, jak a kam vlastně PkYubikey ukládá data o tokenech, nepotřebujete vytvářet registrační okno pro svoji aplikaci. Stačí, když zavoláte PkYubikey.exe s příslušnými parametry (konkrétně -r jméno UID Klíč Počitadlo) a utilita se o registraci tokenu sama postará.

  2. Ověření jména a hesla z programu, kterému nemůžete nebo nechcete opravit zdrojový kód, ale který je schopen si zavolat jiný program a ověřit jeho návratovou hodnotu. To je například případ OpenVPN ve verzích 2.1 a novějších, které umí pracovat i v režimu jméno/heslo; v takovém případě volají externí program a ověřují si jeho návratovou hodnotu (result code, errorlevel). Při volání použijete parametry -a jméno jednorázové heslo, pozitivní výsledek (platná autentizace) je signalizován návratovým kódem nula.

Download

PkYubikey v0.05 (25.10.2010, 71 KB). Pročištěn zdrojový kód. Licence explicitně uvedena jako nová BSD licence. Přidáno číslo verze a digitální podpisy do spustitelných souborů.

PkYubikey v0.03 (15.9.2009, 41 KB).

Podobné příspěvky:

3 komentáře “PkYubikey”

  1. avatar pepak napsal:

    I think that’s only supported with the newer Yubikeys (version 2.2), and as I have the older revision (2.1), I couldn’t test it.

  2. avatar 4e4en napsal:

    What about integrating YubiKey Challenge-Response?

  3. avatar pepak napsal:

    Verze 0.05: Pročištěn zdrojový kód. Licence explicitně uvedena jako nová BSD licence. Přidáno číslo verze a digitální podpisy do spustitelných souborů.

Leave a Reply

Themocracy iconWordPress Themes

css.php