流程
* * 1、平台端生成32位秘钥 ,然后将秘钥和用户账户对应关系存到自己的数据库 * * 2、用户端使用《谷歌身份验证器》添加账户并配置第一步给出的秘钥 (每个用户要有独立秘钥,不能重复) * * 3、用户登录时候输入账户、密码、谷歌验证码 ;后台根据账户查询出秘钥,然后反解析得出当前动态验证码,判断跟用户输入的谷歌验证码是否一样 *
默认使用时间戳的形式进行校验,原理很简单。生成秘钥、绑定秘钥、根据秘钥和时间戳(有冗余误差延时)进行解密,解密的值与用户输入的一致即可。
这种基于约定的加解密,无需中心服务器,属于区块链的一个简单应用场景。
因为《谷歌身份验证器》客户端覆盖面广,所以没必要自己再做一个。
1、maven引入依赖
<!--google两步认证相关-->
<dependency>
<groupId>de.taimos</groupId>
<artifactId>totp</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.10</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.2.1</version>
</dependency>
2、简单的秘钥生成跟解密
import de.taimos.totp.TOTP;
import org.apache.commons.codec.binary.Base32;
import org.apache.commons.codec.binary.Hex;
import java.security.SecureRandom;
/**
* google 二次验证码实现逻辑
*
* 1、平台端生成32位秘钥 ,然后将秘钥和用户账户对应关系存到自己的数据库
*
* 2、用户端使用《谷歌身份验证器》添加账户并配置第一步给出的秘钥 (每个用户要有独立秘钥,不能重复)
*
* 3、用户登录时候输入账户、密码、谷歌验证码 ;后台根据账户查询出秘钥,然后反解析得出当前动态验证码,判断跟用户输入的谷歌验证码是否一样
*
*/
public class GoogleAuthenticationTool {
// 生成32位秘钥
public static String generateSecretKey() {
SecureRandom random = new SecureRandom();
byte[] bytes = new byte[20];
random.nextBytes(bytes);
Base32 base32 = new Base32();
return base32.encodeToString(bytes);
}
/**
* 根据32位随机码获得正确的6位数字
* @param secretKey
* @return
*/
public static String getTOTPCode(String secretKey) {
Base32 base32 = new Base32();
byte[] bytes = base32.decode(secretKey);
String hexKey = Hex.encodeHexString(bytes);
return TOTP.getOTP(hexKey);
}
static String key="UBKHKX2S34GIXGN6HF46C3D44YJF34Z3";
public static void main(String[] args) {
System.out.println(getTOTPCode(key));
}
}