在项目中集成GoogleAuth实现两步验证(2FA)
二步验证最早被Google用于GMail的登录验证,如今已经被运用到了阿里云、Github等大型的网站之中,为账号安全保驾护航。二步验证的加入,可以有效地防止因为用户的账号密码泄露导致对用户数据造成损失。

引入依赖
首先,我们需要在项目中引入GoogleAuth依赖。在本次教程中,我们使用了SpringBoot框架进行演示,你可以根据自己的项目情况进行代码移植。
<dependency>
<groupId>com.warrenstrange</groupId>
<artifactId>googleauth</artifactId>
<version>1.5.0</version>
</dependency>
相关代码
由于GoogleAuth已经完成了校验和生成的内容,所以我们只需要调用相关的函数即可,非常的简单。在这里,我们只需要创建TwoFactorAuthService.java及其实现类TwoFactorAuthServiceImpl.java,并在实现类中完成相应的逻辑即可。这里只是简单的一个Demo,如果要为不同用户设置独立的密钥并进行校验,可以尝试为其设置一个数据库进行存储。
@Service
public class TwoFactorAuthServiceImpl implements TwoFactorAuthService {
private GoogleAuthenticator gAuth = new GoogleAuthenticator();
// 生成并返回二维码密钥
public String generateSecretKey(Long userId) {
GoogleAuthenticatorKey key = gAuth.createCredentials();
return key.getKey();
// TODO: 将生成的key存入数据库中
}
// 验证动态验证码
// TODO: 如果需要支持多用户,可以传入userid等信息
public boolean verifyCode(String key2fa, int verificationCode) {
// TODO: 根据用户id查询是否已经拥有密钥,如果没有,调用generateSecretKey生成
if (key2fa == null) {
key2fa = generateSecretKey(userId);
}
return gAuth.authorize(key2fa, verificationCode);
}
}
运行之后,我们可以直接获取到key2fa的信息。在这里,我们需要拼接到这个uri模板中,并通过生成二维码来绑定到二步验证器中。
otpauth://totp/{issuer}:{account}?secret={secret}&issuer={issuer}
issuer: 服务提供商,可以是你的app的名字
account: 账号,可以是用户的id或者名称
secret: 刚才在控制台打印的key2fa
技术原理
TOTP算法
TOTP 是一种基于时间的动态密码生成算法,是两步验证实现的核心算法。它结合了当前的系统时间和共享密钥(secret),生成一个短时间有效的唯一验证码。关键的实现内容如下:
-
时间步长:TOTP 的步长通常为 30 秒,即每 30 秒生成一个新的验证码。
-
时间戳:将当前的系统时间(通常以 UNIX 时间戳表示)除以步长,得到一个时间段的计数器。
-
HMAC 加密:将计数器和共享密钥(secret)通过 HMAC-SHA1 加密得到一个哈希值。
-
截取输出:从 HMAC 结果中提取 4 字节(31 位)数据,并对其取模(通常取模 10^6),得到一个 6 位验证码。
GoogleAuth的关键组件
- 密钥生成:GoogleAuth库可以生成一个 Base32 编码的共享密钥,用于初始化 TOTP 生成器。这个密钥会被用户的验证器(如 Google Authenticator)和服务器同时使用。
- 生成 OTP:使用 secret 和当前时间戳来生成一次性密码。一般情况下,它每 30 秒生成一个新的 6 位或 8 位数字验证码。
- 验证 OTP:库可以在用户提供的验证码与生成的验证码之间进行比较。如果它们匹配,验证成功,否则验证失败。通常允许一个时间段的偏移,以处理客户端和服务器之间可能存在的小时间差。
发布于:2024年11月08日 11:08
