package com.mange.sys.util;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Base32;
import org.apache.commons.codec.binary.Hex;
import org.bouncycastle.crypto.digests.SHA1Digest;
import org.bouncycastle.crypto.macs.HMac;
import org.bouncycastle.crypto.params.KeyParameter;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Base64;
import java.util.List;
public class GoogleAuthUtil {
/**
* 获取当前时间
* @return
*/
public static long get_cur_time(){
long ctime = System.currentTimeMillis() / 1000 / 30;
return ctime;
}
/**
* 获取上一个时间
* @return
*/
public static long get_pri_time(){
return GoogleAuthUtil.get_cur_time() - 1;
}
/**
* 获取下一个时间
* @return
*/
public static long get_next_time(){
return GoogleAuthUtil.get_cur_time() + 1;
}
/**
* 获取秘钥
* @return
*/
public static byte[] get_key(){
SecureRandom secureRandom = new SecureRandom();
return secureRandom.generateSeed(32);
}
/**
* 获取秘钥 base32
* @return
*/
public static String get_key_base32(){
Base32 base32 = new Base32();
return base32.encodeAsString(GoogleAuthUtil.get_key());
}
/**
* 验证动态面是否正确
* @param base64_key
* @param code
* @return
*/
public static boolean auth_code(String base64_key,String code){
long cur_time = GoogleAuthUtil.get_cur_time();
long pri_time = GoogleAuthUtil.get_pri_time();
long next_time = GoogleAuthUtil.get_next_time();
List<Long> times = Arrays.asList(cur_time, pri_time, next_time);
byte[] hash = null;
byte[] key_byte = Base64.getDecoder().decode(base64_key);
for (Long time : times) {
hash = GoogleAuthUtil.get_hash( GoogleAuthUtil.get_time_byte(time),key_byte);
if (GoogleAuthUtil.get_code(hash).equals(code)){
return true;
}
}
return false;
}
/**
* 生成url
* @param name
* @param key
* @return
*/
public static String get_qrcode_url(String name,byte [] key){
Base32 base32 = new Base32();
String str = base32.encodeAsString(key);
return "otpauth://totp/"+name+"?secret=" + str;
}
public static String get_qrcode_url(String name){
Base32 base32 = new Base32();
String str = base32.encodeAsString(GoogleAuthUtil.get_key());
return "otpauth://totp/"+name+"?secret=" + str;
}
/**
* 获取时间byte
* @param ctime
* @return
*/
public static byte[] get_time_byte(long ctime){
//hex 长度补齐
String hex = Long.toHexString(ctime);
while (hex.length() < 16) hex = "0" + hex;
byte[] time_byte = null;
try {
time_byte = Hex.decodeHex(hex);
} catch (DecoderException e) {
e.printStackTrace();
}
return time_byte;
}
/**
* 根据时间 keu 获得hahs值
* @param time
* @param key_byte
* @return
*/
public static byte[] get_hash(byte[] time,byte[] key_byte){
SHA1Digest digest = new SHA1Digest();
HMac hMac = new HMac(digest);
hMac.init( new KeyParameter(key_byte));
hMac.update(time,0,time.length);
byte [] result = new byte[hMac.getMacSize()];
hMac.doFinal(result,0);
return result;
}
/**
* 根据hash组织计算动态密码
* @param hash
* @return
*/
public static String get_code(byte[] hash){
//偏移量
int offset = hash[20 - 1] & 0xF;
//java 中的int 类型没有无符号类型 所以使用long进行代替
long trunHash = 0;
for (int i = 0; i < 4; ++i) {
trunHash <<= 8;
//处理有符号类型byte 保留第一个字节
trunHash |= (hash[offset + i] & 0xFF);
}
trunHash &= 0x7FFFFFFF;
//取值六位动态密码 0 - 999999
trunHash %= 1000000;
return String.format("%06d", trunHash);
}
}
Google 谷歌身份验证器 JAVA
于 2022-03-25 22:42:22 首次发布
本文介绍了一种基于Google身份验证器的实现方案,包括获取当前时间、生成密钥、验证动态码等功能,并提供了完整的Java代码示例。
Seed-Coder-8B-Base
文本生成
Seed-Coder
Seed-Coder是一个功能强大、透明、参数高效的 8B 级开源代码模型系列,包括基础变体、指导变体和推理变体,由字节团队开源
您可能感兴趣的与本文相关的镜像
Seed-Coder-8B-Base
文本生成
Seed-Coder
Seed-Coder是一个功能强大、透明、参数高效的 8B 级开源代码模型系列,包括基础变体、指导变体和推理变体,由字节团队开源
4622

被折叠的 条评论
为什么被折叠?



