1. 程式人生 > >Token的生成和驗證--Java

Token的生成和驗證--Java

遇到了token驗證的需求,然後下了一個demo,因為我只用到了token的生成和驗證,所以根據自己的需求整理了一下,原版demo下載:http://download.csdn.net/detail/qierkang/9792660
1. 加密工具類,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; } }

2 . token的生成和驗證


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;
    }
}

具體用到哪些jar包,可以下載demo看