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