所以我在使用Google Authenticator和我的PHP时遇到了问题。
因此,我正在使用此库来生成QR码:https://github.com/PHPGangsta/GoogleAuthenticator
因此,当我使用用户名生成代码时,它可以正常工作。我得到一些类似的东西: otpauth:// totp / username?secret = aCodeInBase32&issuer = Mysite
对于我来说是: otpauth:// totp / NoahNok?secret = aCodeInBase32&issuer = JukeHost
但是,当将其用于任何其他用途时,我在Google Authenticator应用上收到无效的令牌错误。我放什么也没关系,我似乎总是会收到此错误,但对我的帐户来说还是可以的。
例如,这不起作用:otpauth:// totp / Test?secret = KRSX&issuer = 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.'';
}
答案 0 :(得分:0)
Base32被填充为最接近的8个字符的倍数,因此它不会总是以====
结尾。从您的示例中,我们得到:
NoahNok => JZXWC2CON5VQ====
和:
Test => KRSXG5A=
因此,如果始终删除最后4个字符,则对于类似后者的情况,您将创建无效的Base32序列。您可以这样使用rtrim
:
$secret = rtrim(Base32::encode($username), '=')
仅删除所有结尾的等号(或保留它们)。
我只是在考虑这个问题,尽管以上内容可以解决最近的问题,但是以这种方式生成秘密可能不是一个好主意。如果您考虑一下,将机密设置为与用户名相同意味着,如果有人找到了用户名,他们可以生成有效的OTP,从而能够通过其2FA。
出于这个目的,秘密应该是唯一的并且通常是不可猜测的,并且您所使用的库具有createSecret
方法来为您执行此操作。