谷歌二步身份验证
前言
现在随处登录都需要填写验证码或者点击相关字符等等模式,此文根据大佬的灵感,结合springboot完成谷歌二次身份验证。此处大佬地址。
一、谷歌二次身份验证是什么?
(此图来源)
谷歌二次身份验证的目的是什么想必大家都清楚,此app类似于steam令牌、企鹅令牌等等,在输入密码登录中的时候,拉取接口完成验证码的校验。
二、使用步骤
1.maven依赖(若不想后台直接生成二维码可不导)
<!-- 二维码依赖 -->
<dependency>
<groupId>org.iherus</groupId>
<artifactId>qrext4j</artifactId>
<version>${
qrext4j.version}</version>
</dependency>
2.工具类代码
工具类:GoogleAuthenticator 提供了生成谷歌秘钥key、校验验证码的功能。
代码如下:
import org.apache.commons.codec.binary.Base32;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.springframework.util.StringUtils;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
/**
* 谷歌身份验证器工具类
*/
public class GoogleAuthenticator {
/**
* 时间前后偏移量
* 用于防止客户端时间不精确导致生成的TOTP与服务器端的TOTP一直不一致
* 如果为0,当前时间为 10:10:15
* 则表明在 10:10:00-10:10:30 之间生成的TOTP 能校验通过
* 如果为1,则表明在
* 10:09:30-10:10:00
* 10:10:00-10:10:30
* 10:10:30-10:11:00 之间生成的TOTP 能校验通过
* 以此类推
*/
private static int WINDOW_SIZE = 0;
/**
* 加密方式,HmacSHA1、HmacSHA256、HmacSHA512
*/
private static final String CRYPTO = "HmacSHA1";
/**
* 生成密钥,每个用户独享一份密钥
*
* @return
*/
public static String getSecretKey() {
SecureRandom random = new SecureRandom();
/*密钥太长不容易输入*/
// byte[] bytes = new byte[20];
/*密钥太短不符合gooleAPP*/
// byte[] bytes = new byte[5];
/*生成16位秘钥*/
byte[] bytes = new byte[10];
random.nextBytes(bytes);
Base32 base32 = new Base32();
String secretKey = base32.encodeToString(bytes);
// make the secret key more human-readable by lower-casing and
// inserting spaces between each group of 4 characters
return secretKey.toUpperCase();
}
/**
* 生成二维码内容
*
* @param secretKey 密钥
* @param account 账户名
* @param issuer 网站地址(可不写)
* @return
*/
public static String getQrCodeText(String secretKey, String account, String issuer) {
String normalizedBase32Key = secretKey.replace(" ", "").toUpperCase();
try {
String s = "otpauth://totp/"
+ URLEncoder.encode((!St