Token的生成和验证

该代码示例展示了如何在Java中生成oken并进行验证,使用XXTEA加密算法确保安全性。oken包含随机生成的字符和时间戳,过期时间设定为30天。解密过程检查oken的格式、时间戳有效性和完整性。
摘要由CSDN通过智能技术生成

oken的生成和验证

import java.util.Random;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang.StringUtils;


public class TokenUtil {

    private static final String[] codeBase= {"0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"};

    private static Random rand= new Random();

    /** XXTEA加密解密的密钥 */
    private static String secKey = "captcha";

    /** token超时门限(天) */
    private static long expire = 30;


    /** 验证码字符数 */
    private static int charCount = 4;

    public static final  String  genToken() {
        StringBuffer sb= new StringBuffer();
        for(int i=0; i<charCount; i++){
            int randInt= Math.abs(rand.nextInt());
            sb.append(codeBase[randInt % codeBase.length]);
        }
        long timestamp= System.currentTimeMillis();
        String token= null;
        token= String.format("%s_%d", sb.toString(), timestamp);
        System.out.println("未加密的token:"+token);
        token= XXTEAUtil.encrypt(token, secKey);
        return token;
    }

    public static final boolean verificationToken(String token) throws StatusInfoException{
        String plainText= XXTEAUtil.decrypt(token, secKey);
        if (StringUtils.isBlank(plainText)){
                throw new IllegalStateException("解密失败,token可能遭到篡改");
            }
            String[] plainTextArr= plainText.split("_");
            if (plainTextArr.length!=2){
                throw new IllegalStateException("token数据格式错误");
            }
            long timestamp= 0;
            try{
                timestamp= Long.parseLong(plainTextArr[1]);
            }catch(NumberFormatException e){
                throw new IllegalStateException("时间戳无效");
            }
            if ((System.currentTimeMillis() - timestamp)>TimeUnit.MILLISECONDS.convert(expire+5, TimeUnit.DAYS)){
                throw new IllegalStateException("token已过期");
            }
        return true;
    }
}

加密工具类,XXTEAUtil

import org.apache.commons.codec.binary.Base64;


public class XXTEAUtil {

    /**
     * 使用密钥加密数据
     * @param plain
     * @param key
     * @return
     */
    public static byte[] encrypt(byte[] plain, byte[] key) {
        if (plain.length == 0) {
            return plain;
        }
        return toByteArray(encrypt(toIntArray(plain, true), toIntArray(key, false)), false);
    }

    /**
     * 使用密钥解密
     * @param cipher
     * @param key
     * @return
     */
    public static byte[] decrypt(byte[] cipher, byte[] key) {
        if (cipher.length == 0) {
            return cipher;
        }
        return toByteArray(decrypt(toIntArray(cipher, false), toIntArray(key, false)), true);
    }

    /**
     * 使用密钥加密数据
     * @param v
     * @param k
     * @return
     */
    public static int[] encrypt(int[] v, int[] k) {
        int n = v.length - 1;

        if (n < 1) {
            return v;
        }
        if (k.length < 4) {
            int[] key = new int[4];

            System.arraycopy(k, 0, key, 0, k.length);
            k = key;
        }
        int z = v[n], y = v[0], delta = 0x9E3779B9, sum = 0, e;
        int p, q = 6 + 52 / (n + 1);

        while (q-- > 0) {
            sum = sum + delta;
            e = sum >>> 2 & 3;
            for (p = 0; p < n; p++) {
                y = v[p + 1];
                z = v[p] += (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z);
            }
            y = v[0];
            z = v[n] += (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z);
        }
        return v;
    }

    /**
     * 使用密钥解密数据
     * @param v
     * @param k
     * @return
     */
    public static int[] decrypt(int[] v, int[] k) {
        int n = v.length - 1;

        if (n < 1) {
            return v;
        }
        if (k.length < 4) {
            int[] key = new int[4];

            System.arraycopy(k, 0, key, 0, k.length);
            k = key;
        }
        int z = v[n], y = v[0], delta = 0x9E3779B9, sum, e;
        int p, q = 6 + 52 / (n + 1);

        sum = q * delta;
        while (sum != 0) {
            e = sum >>> 2 & 3;
        for (p = n; p > 0; p--) {
            z = v[p - 1];
            y = v[p] -= (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z);
        }
        z = v[n];
        y = v[0] -= (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z);
        sum = sum - delta;
        }
        return v;
    }

    /**
     * 字节数组转换为整型数组
     * @param data
     * @param includeLength
     * @return
     */
    private static int[] toIntArray(byte[] data, boolean includeLength) {
        int n = (((data.length & 3) == 0) ? (data.length >>> 2) : ((data.length >>> 2) + 1));
        int[] result;

        if (includeLength) {
            result = new int[n + 1];
            result[n] = data.length;
        } else {
            result = new int[n];
        }
        n = data.length;
        for (int i = 0; i < n; i++) {
            result[i >>> 2] |= (0x000000ff & data[i]) << ((i & 3) << 3);
        }
        return result;
    }

    /**
     * 整型数组转换为字节数组
     * @param data
     * @param includeLength
     * @return
     */
    private static byte[] toByteArray(int[] data, boolean includeLength) {
        int n = data.length << 2;
        if (includeLength) {
            int m = data[data.length - 1];

            if (m > n) {
                return null;
            } else {
                n = m;
            }
        }
        byte[] result = new byte[n];

        for (int i = 0; i < n; i++) {
            result[i] = (byte) ((data[i >>> 2] >>> ((i & 3) << 3)) & 0xff);
        }
        return result;
    }

    /**
     * 先XXXTEA加密,后Base64加密
     * @param plain
     * @param key
     * @return
     */
    public static String encrypt(String plain, String key) {
        String cipher = "";
        byte[] k = key.getBytes();
        byte[] v = plain.getBytes();
        cipher = new String(Base64.encodeBase64(XXTEAUtil.encrypt(v, k)));
        cipher = cipher.replace('+', '-');
        cipher = cipher.replace('/', '_');
        cipher = cipher.replace('=', '.');
        return cipher;
    }

    /**
     * 先Base64解密,后XXXTEA解密
     * @param cipher
     * @param key
     * @return
     */
    public static String decrypt(String cipher, String key) {
        String plain = "";
        cipher = cipher.replace('-', '+');
        cipher = cipher.replace('_', '/');
        cipher = cipher.replace('.', '=');
        byte[] k = key.getBytes();
        byte[] v = Base64.decodeBase64(cipher);
        plain = new String(XXTEAUtil.decrypt(v, k));
        return plain;
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序猿毕业分享网

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值