PHP WebShell

Текущая директория: /var/www/bitcardoApp/lib

Просмотр файла: totp.php

<?php
// lib/totp.php
// Tiny, dependency-free TOTP (RFC 6238) with Base32 helpers.

if (!function_exists('base32_decode')) {
  function base32_decode(string $b32): string {
    $alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';
    $b32 = strtoupper(preg_replace('/[^A-Z2-7]/i', '', $b32));
    $bits = '';
    for ($i=0; $i<strlen($b32); $i++) {
      $v = strpos($alphabet, $b32[$i]);
      if ($v === false) continue;
      $bits .= str_pad(decbin($v), 5, '0', STR_PAD_LEFT);
    }
    $out = '';
    foreach (str_split($bits, 8) as $byte) {
      if (strlen($byte) === 8) $out .= chr(bindec($byte));
    }
    return $out;
  }
}

if (!function_exists('totp_secret_generate')) {
  function totp_secret_generate(int $bytes = 20): string {
    $raw = random_bytes($bytes);
    $alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';
    $bits = '';
    for ($i=0; $i<strlen($raw); $i++) $bits .= str_pad(decbin(ord($raw[$i])), 8, '0', STR_PAD_LEFT);
    $out = '';
    foreach (str_split($bits, 5) as $chunk) {
      if (strlen($chunk) < 5) $chunk = str_pad($chunk, 5, '0', STR_PAD_RIGHT);
      $out .= $alphabet[bindec($chunk)];
    }
    return $out;
  }
}

if (!function_exists('totp_now')) {
  function totp_now(string $secretBase32, int $timeStep = 30, int $digits = 6, ?int $forTime = null): string {
    $key = base32_decode($secretBase32);
    $t = (int)floor((($forTime ?? time())) / $timeStep);
    $bin = pack('N*', 0) . pack('N*', $t);
    $hash = hash_hmac('sha1', $bin, $key, true);
    $offset = ord(substr($hash, -1)) & 0x0F;
    $trunc = (ord($hash[$offset]) & 0x7F) << 24 |
             (ord($hash[$offset+1]) & 0xFF) << 16 |
             (ord($hash[$offset+2]) & 0xFF) << 8  |
             (ord($hash[$offset+3]) & 0xFF);
    $code = $trunc % (10 ** $digits);
    return str_pad((string)$code, $digits, '0', STR_PAD_LEFT);
  }
}

if (!function_exists('totp_verify')) {
  function totp_verify(string $secretBase32, string $code, int $window = 1, int $timeStep = 30, int $digits = 6): bool {
    $code = preg_replace('/\D+/', '', $code);
    if (strlen($code) !== $digits) return false;
    $now = time();
    for ($w = -$window; $w <= $window; $w++) {
      if (hash_equals(totp_now($secretBase32, $timeStep, $digits, $now + $w*$timeStep), $code)) {
        return true;
      }
    }
    return false;
  }
}

Выполнить команду


Для локальной разработки. Не используйте в интернете!