引言:更多相关请看 Java其它
引入依赖:
<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>
代码如下:
import com.google.zxing.BarcodeFormat;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import de.taimos.totp.TOTP;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base32;
import org.apache.commons.codec.binary.Hex;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.SecureRandom;
import java.util.Scanner;
/**
* 谷歌验证
*/
@Slf4j
public class GoogleAuthUtil {
/**
* 谷歌验证每30秒生成一个唯一的验证码,
* 需要
* @param args
*/
public static void main(String[] args) {
// String s1 = generateSecretKey();
String s2 = "NAXLNPSOQER27H7AFJRXLLBVEP23MXL7";
String s = "V2EXFANTGICYYNWUGOHLYNTNDM7D4UUP";
String totpCode = getTOTPCode(s);
System.out.println(totpCode);
String secretKey = "V2EXFANTGICYYNWUGOHLYNTNDM7D4UUP";
String lastCode = null;
boolean b = checkCode(s, "556347");
System.out.println(b);
System.out.println(checkCode(s2, "909953"));
}
/**
* -生成QR码。让我们使用ZXing库
* @param barCodeData
* @param filePath 文件目录
* @param height 高
* @param width 宽
* @throws WriterException
* @throws IOException
*/
public static void createQRCode(String barCodeData, String filePath, int height, int width){
try (FileOutputStream out = new FileOutputStream(filePath)) {
BitMatrix matrix = new MultiFormatWriter().encode(barCodeData, BarcodeFormat.QR_CODE,
width, height);
MatrixToImageWriter.writeToStream(matrix, "png", out);
}catch (Exception e){
e.printStackTrace();
}
}
/**
* 需要从Google接收条形码数据。它需要某种特殊格式,因此这是我们生成此数据的方法。
*
* @param secretKey 秘密密钥
* @param account 帐户是系统中的用户ID。通常是用户的电子邮件或用户名。它用于标记Google Authenticator中的条目。
* @param issuer 发行者是公司或组织的名称,也用于标记目的。
* @return
*/
public static String getGoogleAuthenticatorBarCode(String secretKey, String account, String issuer) {
try {
return "otpauth://totp/"
+ URLEncoder.encode(issuer + ":" + account, "UTF-8").replace("+", "%20")
+ "?secret=" + URLEncoder.encode(secretKey, "UTF-8").replace("+", "%20")
+ "&issuer=" + URLEncoder.encode(issuer, "UTF-8").replace("+", "%20");
} catch (UnsupportedEncodingException e) {
throw new IllegalStateException(e);
}
}
/**
* 检查6位码是否正常
*
* @param secretKey 秘钥
* @param code 六位码
* @return
*/
public static boolean checkCode(String secretKey, String code) {
String totpCode = getTOTPCode(secretKey);
System.out.println("目前的生成的六位码:" + totpCode);
if (totpCode != null && totpCode != "" && code != null && code != "" && totpCode.equals(code)) {
return true;
}
return false;
}
/**
* base32编码的秘密密钥转换为十六进制并使用TOTP根据当前时间将其转换为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);
}
/**
* Google身份验证器需要20个字节的密钥,编码为base32字符串。我们需要使用以下代码生成此密钥
*
* @return
*/
public static String generateSecretKey() {
SecureRandom random = new SecureRandom();
byte[] bytes = new byte[20];
random.nextBytes(bytes);
Base32 base32 = new Base32();
return base32.encodeToString(bytes);
}
}