com.sinszm.sofa.util.OneTimePwdUtil Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of szm-sofa-boot-starter Show documentation
Show all versions of szm-sofa-boot-starter Show documentation
高可用服务框架,公共依赖库 Copyright © 2021 智慧程序猿(sinsz.com) All rights reserved.
The newest version!
package com.sinszm.sofa.util;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base32;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.lang.reflect.UndeclaredThrowableException;
import java.math.BigInteger;
import java.security.GeneralSecurityException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.UUID;
/**
* 一次pwd跑龙套
*
* @author admin
* @date 2022/05/11
*/
@Slf4j
public class OneTimePwdUtil {
/**
* 生成一次性密码(6位)
*
* @return 随机字符串
*/
public static String getOneTimePassword() {
return getOneTimePassword(6);
}
/**
* 生成指定位数一次性密码
*
* @param length 长度:4,6,8,10
* @return 随机字符串
*/
public static String getOneTimePassword(int length) {
return OneTimePwdUtil.generateTOTP(
UUID.randomUUID().toString().replaceAll("-", ""),
System.currentTimeMillis() + "",
length
);
}
private static final int[] DIGITS_POWER = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000};
private static byte[] hmacSha(String crypto, byte[] keyBytes, byte[] text) {
try {
Mac hmac;
hmac = Mac.getInstance(crypto);
SecretKeySpec macKey = new SecretKeySpec(keyBytes, "RAW");
hmac.init(macKey);
return hmac.doFinal(text);
} catch (GeneralSecurityException gse) {
throw new UndeclaredThrowableException(gse);
}
}
private static byte[] hexStr2Bytes(String hex) {
byte[] bArray = new BigInteger("10" + hex, 16).toByteArray();
byte[] ret = new byte[bArray.length - 1];
System.arraycopy(bArray, 1, ret, 0, ret.length);
return ret;
}
static String generateTOTP(String key,
String time,
int digits) {
return generateTOTP(key, time, digits, "HmacSHA1");
}
public static String generateTOTP256(String key,
String time,
int digits) {
return generateTOTP(key, time, digits, "HmacSHA256");
}
public static String generateTOTP512(String key,
String time,
int digits) {
return generateTOTP(key, time, digits, "HmacSHA512");
}
static String generateTOTP(String key,
String time,
int digits,
String crypto) {
StringBuilder result;
StringBuilder timeBuilder = new StringBuilder(time);
while (timeBuilder.length() < 16) {
timeBuilder.insert(0, "0");
}
time = timeBuilder.toString();
byte[] msg = hexStr2Bytes(time);
byte[] k = hexStr2Bytes(key);
byte[] hash = hmacSha(crypto, k, msg);
int offset = hash[hash.length - 1] & 0xf;
int binary = ((hash[offset] & 0x7f) << 24) | ((hash[offset + 1] & 0xff) << 16)
| ((hash[offset + 2] & 0xff) << 8)
| (hash[offset + 3] & 0xff);
int otp = binary % DIGITS_POWER[digits];
result = new StringBuilder(Integer.toString(otp));
while (result.length() < digits) {
result.insert(0, "0");
}
return result.toString();
}
public static class GoogleAuthenticator {
private static final int SECRET_SIZE = 16;
private static final String SEED = "g8GjEvTbW5oVSV7avL473574383462rey567et66dLDVKs2m0QN7vxRs2im5MDaNCWGmcD2rvcZx";
private static final String RANDOM_NUMBER_ALGORITHM = "SHA1PRNG";
public static String generateSecretKey() {
SecureRandom sr;
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) {
log.error("error");
}
return null;
}
}
}