All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sinszm.sofa.util.OneTimePwdUtil Maven / Gradle / Ivy

Go to download

高可用服务框架,公共依赖库 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;
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy