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

net.guerlab.commons.encrypt.AuthCodeHelper Maven / Gradle / Ivy

Go to download

net.guerlab.commons is a suite of core and expanded libraries that include utility classes and much much more.

The newest version!
/*
 * Copyright 2018-2021 guerlab.net and other contributors.
 *
 * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE, Version 3 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.guerlab.commons.encrypt;

import org.apache.commons.codec.digest.DigestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.charset.StandardCharsets;
import java.util.Base64;

/**
 * 混淆加密工具类
 *
 * @author guer
 */
public final class AuthCodeHelper {

    private static final Logger LOGGER = LoggerFactory.getLogger(AuthCodeHelper.class);

    /**
     * 默认随机秘钥长度
     */
    public static final int DEFAULT_KEY_LENGTH = 4;

    private AuthCodeHelper() {
    }

    /**
     * 加密
     *
     * @param str
     *         待加密内容
     * @param key
     *         秘钥
     * @param expiry
     *         有效期,单位毫秒
     * @return 加密结果
     * @throws NullPointerException
     *         当str、key为空的时候抛出NullPointerException异常
     */
    public static String encode(final String str, final String key, final long expiry) {
        return toEncode(str, key, expiry, DEFAULT_KEY_LENGTH);
    }

    /**
     * 加密
     *
     * @param str
     *         待加密内容
     * @param key
     *         秘钥
     * @param expiry
     *         有效期,单位毫秒
     * @param randomKeyLength
     *         随机秘钥长度
     * @return 加密结果
     * @throws NullPointerException
     *         当str、key为空的时候抛出NullPointerException异常
     */
    public static String encode(final String str, final String key, final long expiry, final int randomKeyLength) {
        return toEncode(str, key, expiry, randomKeyLength);
    }

    /**
     * 解密
     *
     * @param str
     *         加密结果
     * @param key
     *         秘钥
     * @return 解密结果
     */
    public static String decode(final String str, final String key) {
        return decode(str, key, DEFAULT_KEY_LENGTH);
    }

    /**
     * 解密
     *
     * @param str
     *         加密结果
     * @param key
     *         秘钥
     * @param randomKeyLength
     *         随机秘钥长度
     * @return 解密结果
     */
    public static String decode(final String str, final String key, final int randomKeyLength) {
        return toDecode(str, key, randomKeyLength);
    }

    /**
     * 解密操作
     *
     * @param str
     *         待加密字符串
     * @param key
     *         加密秘钥
     * @param randomKeyLength
     *         随机秘钥长度
     * @return 解密后字符串
     * @throws NullPointerException
     *         当str、key为空的时候抛出NullPointerException异常
     */
    private static String toDecode(final String str, final String key, final int randomKeyLength) {
        if (str == null) {
            throw new NullPointerException("str can not to be null");
        }

        long nowTime = System.currentTimeMillis() / 1000;

        AuthCodeKey keys = new AuthCodeKey(key);
        String keyC = getKeyC(str, randomKeyLength);
        String cryptKey = keys.getKeyA() + DigestUtils.md5Hex(keys.getKeyA() + keyC);
        String result = getResult(str, randomKeyLength, cryptKey);

        long time = getTime(result);
        if (time <= 0 && time < nowTime) {
            return "";
        }

        if (decodeCheck(result, keys)) {
            return result.substring(26);
        }

        result = getResult(str + "=", randomKeyLength, cryptKey);
        if (decodeCheck(result, keys)) {
            return result.substring(26);
        }

        result = getResult(str + "==", randomKeyLength, cryptKey);
        if (decodeCheck(result, keys)) {
            return result.substring(26);
        }

        return "";
    }

    private static String getKeyC(final String nowStr, final int randomKeyLength) {
        String keyC = "";

        if (randomKeyLength != 0) {
            keyC = nowStr.substring(0, randomKeyLength);
        }

        return keyC;
    }

    private static long getTime(String result) {
        try {
            return Long.parseLong(result.substring(0, 10));
        } catch (Exception e) {
            LOGGER.debug(e.getMessage(), e);
        }
        return 0;
    }

    private static String getResult(final String nowStr, final int randomKeyLength, final String cryptKey) {
        byte[] temp = Base64.getDecoder().decode(nowStr.substring(randomKeyLength));
        return new String(Rc4Helper.encode(temp, cryptKey));
    }

    private static boolean decodeCheck(String result, AuthCodeKey keys) {
        String aString = DigestUtils.md5Hex(result.substring(26) + keys.getKeyB());
        String data = aString.substring(0, 16);
        return result.substring(10, 26).equals(data);
    }

    /**
     * 加密操作
     *
     * @param str
     *         待加密字符串
     * @param key
     *         加密秘钥
     * @param expiry
     *         有效期
     * @param randomKeyLength
     *         随机秘钥长度
     * @return 加密后字符串
     * @throws NullPointerException
     *         当str、key为空的时候抛出NullPointerException异常
     */
    private static String toEncode(final String str, final String key, final long expiry, final int randomKeyLength) {
        if (str == null) {
            throw new NullPointerException("str can not to be null");
        }

        long timestamp = System.currentTimeMillis() / 1000;

        AuthCodeKey keys = new AuthCodeKey(key);

        String keyC = "";

        if (randomKeyLength > 0) {
            String data = DigestUtils.md5Hex(String.valueOf(timestamp));
            keyC = data.substring(data.length() - randomKeyLength);
        }

        String cryptKey = keys.getKeyA() + DigestUtils.md5Hex(keys.getKeyA() + keyC);

        String nowStr = str;

        nowStr = String.format("%010d", expiry > 0 ? timestamp + expiry : 0) + DigestUtils
                .md5Hex(nowStr + keys.getKeyB()).substring(0, 16) + nowStr;

        try {
            byte[] temp = Rc4Helper.encode(nowStr.getBytes(StandardCharsets.UTF_8), cryptKey);
            return keyC + Base64.getEncoder().encodeToString(temp);
        } catch (Exception e) {
            LOGGER.debug(e.getMessage(), e);
        }
        return null;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy