Egyik hitelesítő alkalmazás sem szimpatikus? Írd meg magad ~20 sorban!
Az Ügyfélkapu+ új, két faktoros hitelesítése témájában számos írás és fórum topic született már a PH!-n (Logout-on), azonban nagyjából mindegyik cikk és hozzászóló egy harmadik fél által gyártott program használatát vagy telepítését javasolta (PC-re, mobilra, böngészőbe stb.). Amikor beleástam magam a témába, az eredeti célom az volt, hogy megismerjem a TOTP (RFC 6238) szabványt és hogy kiderítsem, mennyire rocket science egy ilyet saját kezűleg lefejleszteni. Nos, kiderült, hogy nem az, PHP-ban néhány sorból összedobható:
<?php
require_once("Base2n.php");
date_default_timezone_set('Europe/Budapest');
$base32 = new Base2n(5, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', false, true, true);
function h(string $key, int $pad, string $text)
{
$key = str_pad($key, 64, chr(0x00), STR_PAD_RIGHT);
for ($i = strlen($key) - 1; $i >= 0; $i--) {
$key[$i] = chr(ord($key[$i]) ^ $pad);
}
return hash('sha1', $key . $text, true);
}
$t = time();
$t30 = (int)floor($t / 30);
$c = hex2bin(str_pad(dechex($t30), 16, '0', STR_PAD_LEFT));
$key = $base32->decode('IDEJONAZUGYFELKAPUTOLKAPOTT16JEGYUKULCSOD');
$h = h($key, 0x5c, h($key, 0x36, $c));
$o = ord($h[strlen($h) - 1]) & 0x0f;
$r = (ord($h[$o]) & 0x7f) << 24
| ord($h[$o + 1]) << 16
| ord($h[$o + 2]) << 8
| ord($h[$o + 3]);
echo str_pad($r % 1000000, 6, '0', STR_PAD_LEFT) . "\n";
Az igazsághoz persze hozzátartozik, hogy ez a program is behúz egy 3. fél által gyártott kódot, ami a Base32 dekódoláshoz szükséges. Ez azonban egyetlen osztály, aminek forráskódját átnézve könnyen meggyőződhetünk annak ártalmatlanságáról. Valójában erre azért van szükségünk, mert az a "kulcs", amit az ügyfélkapu+ igénylésekor kapunk, nem maga a kulcs, hanem a kulcsnak egy base32 algoritmussal elkódolt változata, amit felhasználás előtt érdemes lehet dekódolnunk (amennyiben azt a TOTP implementációnk igényli).
Egyébként annak, hogy ezidáig (2025. január végéig) nem született ebből a tényleg végtelenül egyszerű kódból blog bejegyzés, pontosan az volt az oka, hogy én magam is benéztem az ún. "kulcs" mibenlétét és nem mint base32-es kódolt tartalomként tekintettem rá, hanem nyers, kódolatlan tartalomra. Ezért az én 6 jegyű kódjaim mindig eltértek a többi implementáció (pl. Google Authenticator, TOTP.APP, FreeOTP) által generált kódoktól. A "kulcs" base32 kódoltságnak megkésett felismerése után jött helyre az implementációm és lettek pontosak a 6 jegyű kódjaim.
Ha gondolod, próbáld ki Te is, vagy csak szimplán köpködd meg a kódot. Mindenféle visszajelzést örömmel veszek. Ha még hasznát is veszed, az külön öröm.