From 3098126d3a131780985336612a1018d9641cac63 Mon Sep 17 00:00:00 2001 From: Ivor Barhansky Date: Thu, 9 May 2024 13:48:45 +0000 Subject: [PATCH] Add TOTP.php --- TOTP.php | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 TOTP.php diff --git a/TOTP.php b/TOTP.php new file mode 100644 index 0000000..ad621b6 --- /dev/null +++ b/TOTP.php @@ -0,0 +1,67 @@ +base32_decode($this->secret); + $binaryTime = pack('N*', 0) . pack('N*', $time); + $hash = hash_hmac('sha1', $binaryTime, $secretKey, true); + $offset = ord($hash[strlen($hash) - 1]) & 0x0F; + $otp = ( + ((ord($hash[$offset]) & 0x7F) << 24) | + ((ord($hash[$offset + 1]) & 0xFF) << 16) | + ((ord($hash[$offset + 2]) & 0xFF) << 8) | + (ord($hash[$offset + 3]) & 0xFF) + ) % 10 ** $digits; + return str_pad((string)$otp, $digits, '0', STR_PAD_LEFT); + } + + private function base32_decode(string $input): string + { + $base32charsFlipped = array_flip(str_split(self::BASE32CHARS)); + $output = ''; + $v = 0; + $vbits = 0; + + for ($i = 0, $j = strlen($input); $i < $j; $i++) { + $v <<= 5; + if ($input[$i] == '=') continue; + $v += $base32charsFlipped[$input[$i]]; + $vbits += 5; + + if ($vbits >= 8) { + $vbits -= 8; + $output .= chr(($v & (0xFF << $vbits)) >> $vbits); + } + } + return $output; + } +}