Слияние кода завершено, страница обновится автоматически
package com.seejoke.network.tom;
import org.apache.commons.codec.binary.Base32;
import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
/**
* @author yangzhongying
* @date 2020/2/30 10:26 下午
**/
public class GoogleAuthenticator {
private static final Logger logger = LoggerFactory.getLogger(GoogleAuthenticator.class);
private static final int SECRET_SIZE = 10;
private static final String SEED = "g8GjEvTbW5oVSV7avL47357438reyhreyuryetredLDVKs2m0QN7vxRs2im5MDaNCWGmcD2rvcZx";
private static final String RANDOM_NUMBER_ALGORITHM = "SHA1PRNG";
/**
* 最多可偏移的时间 default 3 - max 17
*/
static int windowSize = 3;
public void setWindowSize(int s) {
if (s >= 1 && s <= 17) {
windowSize = s;
}
}
public static String genSecret() {
String secret = GoogleAuthenticator.generateSecretKey();
return secret;
}
public static String generateSecretKey() {
SecureRandom sr = null;
try {
sr = SecureRandom.getInstance(RANDOM_NUMBER_ALGORITHM);
sr.setSeed(Base64.decodeBase64(SEED));
byte[] buffer = sr.generateSeed(SECRET_SIZE);
Base32 codec = new Base32();
byte[] bEncodedKey = codec.encode(buffer);
return new String(bEncodedKey);
} catch (NoSuchAlgorithmException e) {
logger.error("error");
}
return null;
}
public static String getQrBarcodeUrl(String user, String host, String secret) {
String format = "https://www.seejoke.com/qrcode?content=otpauth://totp/%s@%s?secret=%s";
return String.format(format, user, host, secret);
}
public static String getQrBarcode(String user, String secret) {
String format = "otpauth://totp/%s?secret=%s";
return String.format(format, user, secret);
}
public boolean checkCode(String secret, long code) {
long timeMsec = System.currentTimeMillis();
Base32 codec = new Base32();
byte[] decodedKey = codec.decode(secret);
long t = (timeMsec / 1000L) / 30L;
for (int i = -windowSize; i <= windowSize; ++i) {
long hash;
try {
hash = verifyCode(decodedKey, t + i);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e.getMessage());
//return false;
}
if (hash == code) {
return true;
}
}
return false;
}
private static int verifyCode(byte[] key, long t) throws NoSuchAlgorithmException, InvalidKeyException {
byte[] data = new byte[8];
long value = t;
for (int i = 8; i-- > 0; value >>>= 8) {
data[i] = (byte) value;
}
SecretKeySpec signKey = new SecretKeySpec(key, "HmacSHA1");
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(signKey);
byte[] hash = mac.doFinal(data);
int offset = hash[20 - 1] & 0xF;
long truncatedHash = 0;
for (int i = 0; i < 4; ++i) {
truncatedHash <<= 8;
truncatedHash |= (hash[offset + i] & 0xFF);
}
truncatedHash &= 0x7FFFFFFF;
truncatedHash %= 1000000;
return (int) truncatedHash;
}
public static void main(String[] args) {
String secret = GoogleAuthenticator.generateSecretKey();
System.out.println("秘钥:" + secret);
// 把这个qrcode生成二维码,用微信小程序搜“OTP令牌” 扫一扫即可接入
String qrcode = GoogleAuthenticator.getQrBarcodeUrl("admin", "127.0.0.1", secret);
System.out.println(qrcode);
}
}
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )