TOTP: PHP Token Generator
Da ich für ein Projekt einen TOTP Generator mittels PHP einbinden wollte und keine weitere Bibliothek installieren wollte, habe ich in Zusammenarbeit mit ChatGPT ein TOTP Token Generator gebastelt.
Fangen wir vorne an. Als erstes braucht man die Variablen für den späteren Token.
$label = "Simon Zipperling";
$issuer = "simon.zipperling.net";
$secret = "55IY2MYYPWKWLEQR2LKLRTXSGYZCBIUWECIHXX36B4YHQGCELD7EB3RU6RZXRI4CBQY2PEDVVAGTGGCAE6M63FOCI6QQY6OWLR7L2DQ";
$expiry = 90;
$length = 6;
$algorithm = "sha512";
Bei $expire
kann die zuvor verhandelte Zeit eingestellt werden; Bei $lenght
die Länge des Tokens und bei $alogorith
der zu verwendende Algorithmus. $secret
gibt den geheimen Schlüssel weiter.
Für die spätere TOTP Funktion brauchen wir aber noch eine Zusatzfunktion.
function base32_decode($base32) {
$base32chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';
$base32charsFlipped = array_flip(str_split($base32chars));
$output = '';
$v = 0;
$vbits = 0;
for ($i = 0, $j = strlen($base32); $i < $j; $i++) {
$v <<= 5;
if ($base32[$i] == ' ') continue;
$v += $base32charsFlipped[$base32[$i]];
$vbits += 5;
if ($vbits >= 8) {
$vbits -= 8;
$output .= chr(($v & (0xFF << $vbits)) >> $vbits);
}
}
return $output;
}
Diese Funktion dekodiert die Base32 aus dem Secret.
function generateToken($secret, $length = 6, $expiry = 30, $algorithm = "sha1") {
$time = floor(time() / $expiry);
$data = pack('J', $time);
$secret = base32_decode($secret);
$hash = hash_hmac($algorithm, $data, $secret, true);
$offset = ord(substr($hash, -1)) & 0x0F;
$truncatedHash = substr($hash, $offset, 4);
$code = unpack('N', $truncatedHash)[1];
$code = $code & 0x7FFFFFFF;
$code = str_pad($code % pow(10, $length), $length, '0', STR_PAD_LEFT);
return $code;
}
Diese Funktion erstellt nun den eigentlichen TOTP Token. Dieser kann mit diesem Aufruf benutzt werden:
$token = generateToken("55IY2MYYPWKWLEQR2LKLRTXSGYZCBIUWECIHXX36B4YHQGCELD7EB3RU6RZXRI4CBQY2PEDVVAGTGGCAE6M63FOCI6QQY6OWLR7L2DQ", 6, 30, "sha1");
echo $token;