PHP - Google 身份验证器 URI 代码并不总是有效

PHP - Google Authenticator URI codes don't always work

所以我在使用 google 验证器和我的 PHP 时遇到了问题。

所以我正在使用这个库生成二维码:https://github.com/PHPGangsta/GoogleAuthenticator

因此,当我使用我的用户名生成代码时,它工作正常。我得到一些类似的东西: otpauth://totp/username?secret=aCodeInBase32&issuer=Mysite

对于我的情况是: otpauth://totp/NoahNok?secret=aCodeInBase32&issuer=Mysite

然而,当为任何其他用途执行此操作时,我在 Google Authenticator 应用程序上收到无效令牌错误。不管我放什么,我似乎总是收到此错误,但它对我的帐户来说工作正常。

例如这个不起作用:otpauth://totp/Test?secret=KRSX&issuer=MySite

我有什么明显的错误吗?

我使用的代码: 获取数据之前的一些查询

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

生成二维码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.'';
}

Base32 被填充到最接近的 8 个字符的倍数,所以它不会总是在末尾有 ==== 来剥离。从您的示例中我们得到:

NoahNok => JZXWC2CON5VQ====

和:

Test => KRSXG5A=

因此,如果您始终删除最后 4 个字符,您将在类似后者的情况下创建无效的 Base32 序列。您可以像这样使用 rtrim

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

只删除所有尾随的等号(或只保留它们)。

编辑

我只是在考虑这个,虽然上面的方法可以解决最接近的问题,但以这种方式生成秘密可能不是一个好主意。如果您考虑一下,将秘密设置为用户名意味着如果有人找到用户名,他们可以生成有效的 OTP,因此能够通过他们的 2FA。

Secret 应该是唯一的,并且通常不能被猜到,您正在使用的库有一个 createSecret 方法可以为您做到这一点。