URI-коды Google Authenticator не всегда работают

Так что у меня проблема с аутентификатором Google и моим PHP.

Поэтому я использую эту библиотеку для генерации QR-кодов: https://github.com/PHPGangsta/GoogleAuthenticator

Поэтому, когда я использую свое имя пользователя для генерации кода, он работает нормально. Я получаю что-то вроде:
otpauth: // TOTP / имя пользователя секрет = aCodeInBase32&Эмитент = MySite

Для моего случая это:
otpauth: // TOTP / NoahNok секрет = aCodeInBase32&Эмитент = JukeHost

однако, делая это для любого другого использования, я получаю неверную ошибку токена в приложении Google Authenticator. Неважно, что еще я положил, я всегда получаю эту ошибку, но она прекрасно работает для моей учетной записи.

Например, этот не работает: otpauth: // totp / Test? Secret = KRSX&Эмитент = JukeHost

Есть что-то очевидное, что я делаю неправильно?

Код, который я использую:
Несколько запросов, прежде чем получить данные

$g = new PHPGangsta_GoogleAuthenticator();
include("Base32.php");
$secret = substr(Base32::encode($username),0,-4);
echo $g->getQRCodeGoogleUrl($username, $secret, "JukeHost");

Создает QR URL

    public function getQRCodeGoogleUrl($name, $secret, $title = null, $params = array())
{
$width = !empty($params['width']) && (int) $params['width'] > 0 ? (int) $params['width'] : 200;
$height = !empty($params['height']) && (int) $params['height'] > 0 ? (int) $params['height'] : 200;
$level = !empty($params['level']) && array_search($params['level'], array('L', 'M', 'Q', 'H')) !== false ? $params['level'] : 'M';

$urlencoded = urlencode('otpauth://totp/'.$name.'?secret='.$secret.'');
if (isset($title)) {
$urlencoded .= urlencode('&issuer='.urlencode($title));
}

return 'https://chart.googleapis.com/chart?chs='.$width.'x'.$height.'&chld='.$level.'|0&cht=qr&chl='.$urlencoded.'';
}

1

Решение

Base32 дополняется до ближайшего кратного из 8 символов, поэтому не всегда ==== в конце раздеться. Из ваших примеров мы получаем:

NoahNok => JZXWC2CON5VQ====

а также:

Test => KRSXG5A=

Поэтому, если вы удаляете последние 4 символа всегда, вы создадите недопустимую последовательность Base32 для ситуаций, подобных последним. Вы могли бы вместо этого использовать rtrim вот так:

$secret = rtrim(Base32::encode($username), '=')

просто удалить все конечные равные (или просто оставить их в).

редактировать

Я просто думал об этом, и хотя вышеизложенное исправит ближайшую проблему, генерация секрета таким образом, вероятно, не очень хорошая идея. Если вы думаете об этом, установка секретного значения равным имени пользователя означает, что если кто-то найдет имя пользователя, он может сгенерировать действительный OTP и, следовательно, сможет передать свой 2FA.

Секрет должен быть уникальным и, как правило, неосуществимым для этой цели, а используемая вами библиотека имеет createSecret способ сделать это для вас.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]