在当今的网络安全环境中,两步验证已成为保护用户账户免受未授权访问的重要手段。Google Authenticator是一个流行的两步验证应用程序,它通过生成一次性密码(OTP)来增强账户的安全性。本文将介绍如何实现Google Authenticator的OTP生成机制,并提供PHP代码示例。
两步验证,又称为双因素认证,是一种安全措施,要求用户在登录过程中提供两种形式的身份验证。这通常包括用户知道的信息(如密码)和用户拥有的信息(如手机生成的一次性密码)。这种机制大大降低了个人Google账户信息被他人窃取的风险,因为即使黑客获取了用户的用户名和密码,他们还需要获取用于生成六位数字组合的个人密钥。
OTP的生成过程基于RFC6238标准。首先,需要一个以base32编码的密钥。例如:
GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ
这个密钥实际上是一个base32编码的字符串。选择base32而不是base64的原因包括:
简而言之,编码后的消息比base64更容易记忆。
OTP的生成还涉及到时间因素,更准确地说,是以30秒为间隔。考虑到不是所有设备都使用NTP进行同步,可能需要检查3-5个连续的代码以确保正确的代码被输入。解决方案越安全,可能想要检查的30秒间隔就越少。
让使用当前的Unix时间戳来计算HOTP(基于HMAC的一次性密码)。
UnixTimeStamp (time()/30): 44376117.366667
需要计算6位数字的代码。首先,取上述值的截断:
44376117
然后将其转换为十六进制:
2a52035
打包成字节字符串:
0x20a52035
如果十六进制字符串少于16个字符,则使用0字符从左侧填充。
十进制表示:
0 0 0 0 2 165 32 53
现在计算sha1 HMAC:
hash_hmac('sha1', '...<¥ 5...', '12345678901234567890')
计算结果:
af2b88048dc8979b528af4e37085061d88aaaaa5
将此转换为6位数字序列:
最终结果为:
895250
这就是Google Authenticator应用程序生成的结果。
以下是使用PHP实现上述算法的示例代码。
首先,需要一些库来简化开发。对于PHP,可以使用:
基于RFC6238的实现:
rfc6238.php
包含帮助类TokenAuth6238,具有多个有用功能。
密钥用于为应用程序和生成代码的设备提供基础,以验证用户的身份。密钥很重要,应该通过安全通道传输。如果攻击者获取了密钥,他们就可以生成验证代码并绕过安全程序。
secret = Base32::encode("yourrandomsecretkey");
Google提供了Android和iPhone应用程序,用于为用户生成验证代码。安装应用程序并创建一个新帐户,输入上一步生成的代码。按照意愿命名帐户,并选择基于时间的令牌。现在,可以在智能手机上看到一个6位长的密码,允许验证用户的身份。
现在有了密钥,智能手机正在生成验证代码,让尝试验证它。
<?php
require_once("rfc6238.php");
$secretkey = 'GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ';
$currentcode = '571427';
if (TokenAuth6238::verify($secretkey, $currentcode)) {
echo "Code is valid\n";
} else {
echo "Invalid code\n";
}
?>
也可以使用库自己生成验证代码。
print TokenAuth6238::getTokenCodeDebug($secretkey, 0);
还可以生成一个图像,该图像可以被移动设备用于配置认证程序:
print sprintf('', TokenAuth6238::getBarCodeUrl('', '', $secretkey));
https://github.com/Voronenko/PHPOTP