//生成P加密参数:
package com.paic.pad.info.common.utils;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.Key;
import java.util.Arrays;
import java.util.Date;
import java.util.Random;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class Aes128CbcUtils {
protected final static Log logger = LogFactory.getLog(Aes128CbcUtils.class);
// 算法名称
final static String KEY_ALGORITHM = "AES";
// 加解密算法/模式/填充方式
final static String CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding";
// 字符集
final static String CHARSET_NAME = "UTF-8";
// 填充矢量
final static byte[] iv = {0x30, 0x31, 0x30, 0x32, 0x30, 0x33, 0x30, 0x34, 0x30, 0x35, 0x30, 0x36, 0x30, 0x37, 0x30, 0x38};
//final static byte[] iv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
private static Key getKey(byte[] keyBytes) {
// 如果密钥不足16位,那么就补足
int base = 16;
if ((keyBytes.length % base) != 0) {
int groups = (keyBytes.length / base) + ((keyBytes.length % base) != 0 ? 1 : 0);
byte[] temp = new byte[groups * base];
Arrays.fill(temp, (byte) 0);
System.arraycopy(keyBytes, 0, temp, 0, keyBytes.length);
keyBytes = temp;
}
// 转化成JAVA的密钥格式
return new SecretKeySpec(keyBytes, KEY_ALGORITHM);
}
/**
* 加密方法
*
* @param content 要加密的字符串
* @param key 加密密钥
* @return
*/
public static String encrypt(String content, String key) {
try {
byte[] enc = encrypt(content.getBytes(CHARSET_NAME), key.getBytes(CHARSET_NAME));
String base64Str = Base64.encodeBase64String(enc);
return new String(base64Str.getBytes(), CHARSET_NAME);
}
catch (UnsupportedEncodingException e) {
logger.error(" 加密密钥异常 " , e);
}
return null;
}
/**
* 加密方法
*
* @param content 要加密的字符串
* @param keyBytes 加密密钥
* @return
*/
public static byte[] encrypt(byte[] content, byte[] keyBytes) {
byte[] encryptedText = null;
try {
Key key = getKey(keyBytes);
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
encryptedText = cipher.doFinal(content);
}
catch (Exception e) {
logger.error(" 加密密钥异常 " , e);
}
return encryptedText;
}
/**
* 解密方法
*
* @param encryptedData 要解密的字符串
* @param keyBytes 解密密钥
* @return
*/
public static String decrypt(String encryptedData, String key) {
try {
byte[] enc = encryptedData.getBytes(CHARSET_NAME);
enc = Base64.decodeBase64(enc);
byte[] dec = decrypt(enc, key.getBytes(CHARSET_NAME));
return new String(dec, CHARSET_NAME);
}
catch (UnsupportedEncodingException e) {
logger.error(" 解密密钥异常 " , e);
}
return null;
}
/**
* 解密方法
*
* @param encryptedData 要解密的字符串
* @param keyBytes 解密密钥
* @return
*/
public static byte[] decrypt(byte[] encryptedData, byte[] keyBytes) {
byte[] encryptedText = null;
try {
Key key = getKey(keyBytes);
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
encryptedText = cipher.doFinal(encryptedData);
}
catch (Exception e) {
logger.error(" 解密密钥异常 " , e);
}
return encryptedText;
}
public static void main(String[] args) throws Exception {
/*//加解密 密钥
byte[] keybytes = "paic1234".getBytes();
String content = "a=1&b=2&c=3";
// 加密字符串
System.out.println("加密前的:" + content);
System.out.println("加密密钥:" + new String(keybytes));
// 加密方法
byte[] enc = Aes128CbcUtils.encrypt(content.getBytes(), keybytes);
System.out.println("加密后的内容:" + new String(Hex.encode(enc)));
// 解密方法
byte[] dec = Aes128CbcUtils.decrypt(enc, keybytes);
System.out.println("解密后的内容:" + new String(dec));*/
// 加解密 密钥
String key = "83519aa6d30ecdc3";// "paic1234";
long timestamp = new Date().getTime();
long nonce = new Random().nextInt(100000);
String toSign = timestamp+""+nonce;
System.out.println("signature:" + toSign);
String signature = HmacSHA1Utils.getSignature(toSign, key);
String content = "timestamp="+timestamp+"&nonce="+nonce+"&signature="+signature+"&umId=LIUKAIHUA001";
// 加密字符串
System.out.println("加密前的:" + content);
System.out.println("加密密钥:" + key);
// 加密方法
String enc = Aes128CbcUtils.encrypt(content, key);
System.out.println("加密后的内容:" + enc);
//URL encode
enc = URLEncoder.encode(enc, CHARSET_NAME);
System.out.println("URL encode:" + enc);
//URL decode
String dec = URLDecoder.decode(enc, CHARSET_NAME);
System.out.println("URL decode:" + dec);
// 解密方法
dec = Aes128CbcUtils.decrypt(dec, key);
System.out.println("解密后的内容:" + dec);
}
}
验证P参数:
String p = request.getParameter("p");
String reqUrl = request.getParameter("toUrl");
String toUrl = reqUrl.replace(request.getContextPath(), "");
HttpSession session = request.getSession();
boolean hasSession = (session != null) && (session.getAttribute(SessionKeyConstant.SESSION_LOGIN_USER) != null);
String dispatchUrl = "forward:" + toUrl;
String key = PropertyUtils.getProperty("req.auth.key");//密钥
String vaildTime = PropertyUtils.getProperty("req.auth.requestVaildTime");//有效时间5000毫秒
if(hasSession) {
UserDTO user = (UserDTO) session.getAttribute(SessionKeyConstant.SESSION_LOGIN_USER);
String currUmId = user.getUmId();
//免登录请求
if(StringUtils.isNotEmpty(p)) {
try {
//1. URL decode
//p = URLDecoder.decode(p, "UTF-8");
//2. 解密
String nameValuePairs = Aes128CbcUtils.decrypt(p, key);
//3. 请求验签 和 时效验证
String timestamp = CommonUtils.getValueByKey(nameValuePairs, "timestamp");
String nonce = CommonUtils.getValueByKey(nameValuePairs, "nonce");
String toSign = timestamp+""+nonce;
String umId = CommonUtils.getValueByKey(nameValuePairs, "umId");
String customerId = CommonUtils.getValueByKey(nameValuePairs, "customerId");
String actualSign = HmacSHA1Utils.getSignature(toSign, key);
String exceptedSign = CommonUtils.getValueByKey(nameValuePairs, "signature");
boolean isSignatureVaild = StringUtils.equals(actualSign, exceptedSign);
long requestVaildTime = Long.parseLong(vaildTime);
long requestTimestamp = new Long(timestamp);
long currTimestamp = new Date().getTime();
boolean isRequestVaild = ((currTimestamp-requestTimestamp) < requestVaildTime);
//验证session里用户的umId是否和传过来的umId一致。
if(!StringUtils.equalsIgnoreCase(currUmId, umId)) {
dispatchUrl = "redirect:/404.html";
logger.info("有session用户umId不一致。p=" + p + "currUmId=" + currUmId + ",umId=" + umId);
}
else {
//清除session里的customerId
if(StringUtils.isEmpty(customerId)){
//SESSION_CONTACT_ID 对应的值是customerId
session.removeAttribute(SessionKeyConstant.SESSION_CONTACT_ID);
}
//验证umId通过
else {
if(isSignatureVaild && isRequestVaild && StringUtils.isNotEmpty(umId)) {
//SESSION_CONTACT_ID 对应的值是customerId
session.setAttribute(SessionKeyConstant.SESSION_CONTACT_ID, customerId);
}
}
}
}
catch (Exception e) {
logger.warn("解密异常:" + p, e);
dispatchUrl = "redirect:/404.html";
}
}
session.setAttribute(SessionKeyConstant.SESSION_REQ_AUTH_SUCC, new Boolean(true));
}
/**
*
* 根据key取出解密后的参数值
*
* @param context 解密后的内容
* @param key 参数的key
* @return
*/
public static String getValueByKey(String context, String key) {
String result = "";
if(StringUtils.isNotEmpty(context)){
String[] arr = context.split("&");
for (int i = 0; i < arr.length; i++) {
if(arr[i].indexOf("=") != -1) {
String k = arr[i].substring(0, arr[i].indexOf("="));
String value = arr[i].substring(arr[i].indexOf("=")+1, arr[i].length());
if(key.equals(k)){
result = value;
break;
}
}
}
}
return result;
}