定义枚举类型,包含已经集成的加密算法
package com.sunld.manager_core.tools.encipher.enums;
/**
* @author 孙辽东
* <p>createDate:2014年3月7日 上午11:30:44</p>
* @version V1.0
*/
public enum EncipherEnum {
BASE64,
MD5,
SHA,
HMAC,
DES
}
设计工厂模式,定义了加密和解密抽象方法,并且使用反射实例化具体的Factory
package com.sunld.manager_core.tools.encipher.factory;
import com.sunld.manager_core.exception.BusinessException;
import com.sunld.manager_core.factory.FactoryInterface;
import com.sunld.manager_core.file.property.PropertyUtil;
import com.sunld.manager_core.tools.encipher.enums.EncipherEnum;
import com.sunld.manager_core.util.rtti.ClassUtils;
/**
* <p>加密工厂类</p>
* @author 孙辽东
* <p>createDate:2014年3月7日 上午11:27:08</p>
* @version V1.0
*/
public abstract class EncipherFactory implements FactoryInterface{
protected static final String ENCIPHERKEY = PropertyUtil.getPropertyValue(
"SYSTEM.ENCIPHERKEY");
/**
* <p>Protected constructor to prevent instantiation.
* Use {@link #newInstance}</p>
* <p>createDate:2014年3月7日 上午11:29:35</p>
*/
protected EncipherFactory(){}
/**
*
* @param encipherEnum {@link EncipherEnum}
* @return EncipherFactory
* <p>createDate:2014年3月7日 上午11:30:59</p>
*/
public static EncipherFactory
newInstance(EncipherEnum encipherEnum){
try {
return (EncipherFactory) ClassUtils.forName(PropertyUtil.getPropertyValue(
"SYSTEM."+encipherEnum)).newInstance();
}
catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
throw new BusinessException(
"很抱歉,名称为"+encipherEnum+
"的获取加密算法的具体工厂还没创建!",e);
}
}
public abstract String
encrypt(String str);
public abstract String
decrypt(String str);
}
具体实现
BASE64Encipher
package com.sunld.manager_core.tools.encipher.encipherstrategy;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import com.sunld.manager_core.exception.BusinessException;
import com.sunld.manager_core.exception.ExceptionUtil;
import com.sunld.manager_core.tools.encipher.factory.EncipherFactory;
import com.sunld.manager_core.util.other.StringUtil;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
/**
* <p>BASE64的加密解密是双向的,可以求反解。</p>
* @author 孙辽东
* <p>createDate:2014年3月7日 上午11:40:59</p>
* @version V1.0
*/
public class BASE64Encipher extends EncipherFactory{
public String
encrypt(String str) {
if(StringUtil.isNotNull(str)){
byte[] b =
null;
try {
b = (str+ENCIPHERKEY).getBytes(
"utf-8");
}
catch (UnsupportedEncodingException e) {
throw new BusinessException(
"采用BASE64算法加密失败:"+ExceptionUtil.formatException(e),e);
}
return (
new BASE64Encoder()).encodeBuffer(b);
}
else{
return "";
}
}
public String
decrypt(String str) {
if(StringUtil.isNotNull(str)){
String result =
"";
try {
byte[] b = (
new BASE64Decoder()).decodeBuffer(str);
result =
new String(b,
"utf-8");
result = result.substring(
0,result.indexOf(ENCIPHERKEY));
}
catch (IOException e) {
throw new BusinessException(
"采用BASE64算法解密失败:"+ExceptionUtil.formatException(e),e);
}
return result;
}
else{
return "";
}
}
}
DESPlusEncipher
package com.sunld.manager_core.tools.encipher.encipherstrategy;
import java.security.Key;
import java.security.Security;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import com.sunld.manager_core.exception.BusinessException;
import com.sunld.manager_core.exception.ExceptionUtil;
import com.sunld.manager_core.tools.encipher.factory.EncipherFactory;
import com.sunld.manager_core.util.other.StringUtil;
/**
* <p>DES DES-Data Encryption Standard,即数据加密算法。DES算法的入口参数有三个:Key、Data、Mode。</p>
* <p>Key:8个字节共64位,是DES算法的工作密钥;</p>
* <p>Data:8个字节64位,是要被加密或被解密的数据;</p>
* <p>Mode:DES的工作方式,有两种:加密或解密。</p>
* @author 孙辽东
* <p>createDate:2014年3月7日 下午1:35:34</p>
* @version V1.0
*/
public class DESPlusEncipher extends EncipherFactory{
private Cipher encryptCipher =
null;
private Cipher decryptCipher =
null;
/**
* 完成信息初始化
* <p>createDate:2014年3月7日 下午1:57:34</p>
*/
public DESPlusEncipher(){
Security.addProvider(
new com.sun.crypto.provider.SunJCE());
Key key = getKey(ENCIPHERKEY.getBytes());
try{
encryptCipher = Cipher.getInstance(
"DES");
encryptCipher.init(Cipher.ENCRYPT_MODE, key);
decryptCipher = Cipher.getInstance(
"DES");
decryptCipher.init(Cipher.DECRYPT_MODE, key);
}
catch(Exception e){
throw new BusinessException(
"构造DES加密器时出错!",e);
}
}
public String
encrypt(String str) {
try {
return StringUtil.byteArray2HexStr(encryptCipher.doFinal(str.getBytes()));
}
catch (IllegalBlockSizeException | BadPaddingException e) {
throw new BusinessException(
"采用DES算法加密失败:"+ExceptionUtil.formatException(e),e);
}
}
public String
decrypt(String str) {
try {
return new String(decryptCipher.doFinal(StringUtil.hexStr2ByteArray(str)));
}
catch (IllegalBlockSizeException | BadPaddingException e) {
throw new BusinessException(
"采用DES算法解密失败:"+ExceptionUtil.formatException(e),e);
}
}
/**
* <p>从指定字符串生成密钥,密钥所需的字节数组长度为8位 不足8位时后面补0,超出8位只取前8位</p>
* @param arrBTmp
* @return Key
* <p>createDate:2014年3月7日 下午1:59:01</p>
*/
private Key
getKey(
byte[] arrBTmp){
byte[] arrB =
new byte[
8];
for (
int i =
0; i < arrBTmp.length && i < arrB.length; i++) {
arrB[i] = arrBTmp[i];
}
Key key =
new javax.crypto.spec.SecretKeySpec(arrB,
"DES");
return key;
}
}
HMACEncipher
package com.sunld.manager_core.tools.encipher.encipherstrategy;
import java.math.BigInteger;
import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import com.sunld.manager_core.exception.BusinessException;
import com.sunld.manager_core.exception.ExceptionUtil;
import com.sunld.manager_core.tools.encipher.factory.EncipherFactory;
import com.sunld.manager_core.util.other.StringUtil;
/**
* <p>HMAC是单向加密,任何数据加密后只会产生唯一的一个加密串,通常用来校验数据在传输过程中是否被修改。</p>
* <p>HMAC算法有一个密钥,增强了数据传输过程中的安全性,强化了算法外的不可控因素。</p>
* @author 孙辽东
* <p>createDate:2014年3月7日 下午1:21:57</p>
* @version V1.0
*/
public class HMACEncipher extends EncipherFactory{
private static final String MACKEY =
"HmacMD5";
public String
encrypt(String str) {
if(StringUtil.isNotNull(str)){
String result =
"";
try{
SecretKey secretKey =
new SecretKeySpec(ENCIPHERKEY.getBytes(), MACKEY);
Mac mac = Mac.getInstance(secretKey.getAlgorithm());
mac.init(secretKey);
byte[] b = mac.doFinal((str+ENCIPHERKEY).getBytes());
result = (
new BigInteger(b)).toString(
16);
}
catch(Exception e){
throw new BusinessException(
"采用HMAC算法加密失败:"+ExceptionUtil.formatException(e),e);
}
return result;
}
else{
return "";
}
}
public String
decrypt(String str) {
throw new BusinessException(
"HMAC加密算法是单项的,不能进行反向解密");
}
/**
* 签名工具
* @return String
* <p>createDate:2014年3月7日 下午1:25:53</p>
*/
public String
initMacKey(){
String key =
"";
try{
KeyGenerator keyGenerator = KeyGenerator.getInstance(MACKEY);
SecretKey secretKey = keyGenerator.generateKey();
byte[] b = secretKey.getEncoded();
String str =
new String(b);
key = str;
}
catch(Exception e){
throw new BusinessException(
"在使用HMAC加密算法获取密钥时出错:"+ExceptionUtil.formatException(e),e);
}
return key;
}
}
MD5Encipher
package com.sunld.manager_core.tools.encipher.encipherstrategy;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import com.sunld.manager_core.exception.BusinessException;
import com.sunld.manager_core.exception.ExceptionUtil;
import com.sunld.manager_core.tools.encipher.factory.EncipherFactory;
import com.sunld.manager_core.util.other.StringUtil;
/**
* <p>MD5是单向加密,任何数据加密后只会产生唯一的一个加密串,通常用来校验数据在传输过程中是否被修改。</p>
* @author 孙辽东
* <p>createDate:2014年3月7日 下午1:05:16</p>
* @version V1.0
*/
public class MD5Encipher extends EncipherFactory{
public String
encrypt(String str) {
if(StringUtil.isNotNull(str)){
String result =
"";
MessageDigest md;
try {
md = MessageDigest.getInstance(
"MD5");
md.update((str+ENCIPHERKEY).getBytes());
byte[] b = md.digest();
result = StringUtil.byteArray2HexStr(b);
}
catch (NoSuchAlgorithmException e) {
throw new BusinessException(
"采用MD5算法加密失败:"+ExceptionUtil.formatException(e),e);
}
return result;
}
else{
return "";
}
}
public String
decrypt(String str) {
throw new BusinessException(
"MD5加密算法是单项的,不能进行反向解密");
}
}
SHAEncipher
package com.sunld.manager_core.tools.encipher.encipherstrategy;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import com.sunld.manager_core.exception.BusinessException;
import com.sunld.manager_core.exception.ExceptionUtil;
import com.sunld.manager_core.tools.encipher.factory.EncipherFactory;
import com.sunld.manager_core.util.other.StringUtil;
/**
* <p>SHA是单向加密,任何数据加密后只会产生唯一的一个加密串,通常用来校验数据在传输过程中是否被修改。</p>
* @author 孙辽东
* <p>createDate:2014年3月7日 下午1:18:48</p>
* @version V1.0
*/
public class SHAEncipher extends EncipherFactory{
public String
encrypt(String str) {
if(StringUtil.isNotNull(str)){
String result =
"";
MessageDigest md;
try {
md = MessageDigest.getInstance(
"SHA");
md.update((str+ENCIPHERKEY).getBytes());
byte[] b = md.digest();
result = StringUtil.byteArray2HexStr(b);
}
catch (NoSuchAlgorithmException e) {
throw new BusinessException(
"采用SHA算法加密失败:"+ExceptionUtil.formatException(e),e);
}
return result;
}
else{
return "";
}
}
public String
decrypt(String str) {
throw new BusinessException(
"SHA加密算法是单项的,不能进行反向解密");
}
}
根据不同的加密算法生成相关的key
KeyStrategy
package com.sunld.manager_core.tools.encipher.keystrategy;
import com.sunld.manager_core.factory.LogDefinitionFactory;
/**
* @author 孙辽东
* <p>createDate:2014年5月29日 上午11:37:18</p>
* @version V1.0
*/
public interface KeyStrategy extends LogDefinitionFactory{
public abstract String
toKey(String paramString, Object paramObject);
}
AbstractKeyStrategy
package com.sunld.manager_core.tools.encipher.keystrategy;
import java.util.regex.Pattern;
import com.sunld.manager_core.tools.encipher.enums.EncipherEnum;
import com.sunld.manager_core.tools.encipher.factory.EncipherFactory;
/**
* @author 孙辽东
* <p>createDate:2014年5月29日 上午11:41:04</p>
* @version V1.0
*/
public abstract class AbstractKeyStrategy implements KeyStrategy{
private static final int DEFAULT_MAX_KEY_LENGTH =
250;
private static final Pattern CLEAN_PATTERN = Pattern.compile(
"\\s");
private int maxKeyLength;
public AbstractKeyStrategy(){
this.maxKeyLength = DEFAULT_MAX_KEY_LENGTH;
}
public String
toKey(String regionName, Object key) {
if (key ==
null) {
throw new IllegalArgumentException(
"key must not be null");
}
String keyString = concatenateKey(regionName, transformKeyObject(key));
if (keyString.length() >
this.maxKeyLength) {
return truncateKey(keyString);
}
String finalKey = CLEAN_PATTERN.matcher(keyString).replaceAll(
"");
LOGGER.debug(
"Final cache key: [{" + finalKey +
"}]");
return finalKey;
}
protected abstract String
transformKeyObject(Object paramObject);
protected String
truncateKey(String key){
String keyHashCode = EncipherFactory.newInstance(EncipherEnum.MD5).encrypt(key);
LOGGER.warn(
"Encoded key [{" + key +
"}] to md5 hash [{" + keyHashCode +
"}]. " +
"Be sure to set cache region names whenever possible as the names Hibernate generates are really long.");
return keyHashCode;
}
public int getMaxKeyLength() {
return this.maxKeyLength;
}
public void setMaxKeyLength(
int maxKeyLength) {
this.maxKeyLength = maxKeyLength;
}
protected String
concatenateKey(String regionName, Object key) {
return regionName +
":" + String.valueOf(key);
}
}
HashCodeKeyStrategy
package com.sunld.manager_core.tools.encipher.keystrategy;
/**
* @author 孙辽东
* <p>createDate:2014年5月29日 上午11:40:28</p>
* @version V1.0
*/
public class HashCodeKeyStrategy extends AbstractKeyStrategy{
protected String
transformKeyObject(Object key){
int hashCode = key.hashCode();
if (LOGGER.isInfoEnabled())
LOGGER.info(
"Transformed key [{" + key +
"}] to hashCode [{" + hashCode +
"}]");
return String.valueOf(hashCode);
}
}
Md5KeyStrategy
package com.sunld.manager_core.tools.encipher.keystrategy;
import com.sunld.manager_core.tools.encipher.enums.EncipherEnum;
import com.sunld.manager_core.tools.encipher.factory.EncipherFactory;
/**
* @author 孙辽东
* <p>createDate:2014年5月29日 上午11:49:13</p>
* @version V1.0
*/
public class Md5KeyStrategy extends HashCodeKeyStrategy{
protected String
concatenateKey(String regionName, Object key){
String longKey =
super.concatenateKey(regionName, key);
return EncipherFactory.newInstance(EncipherEnum.MD5).encrypt(longKey);
}
}
Sha1KeyStrategy
package com.sunld.manager_core.tools.encipher.keystrategy;
import com.sunld.manager_core.tools.encipher.enums.EncipherEnum;
import com.sunld.manager_core.tools.encipher.factory.EncipherFactory;
/**
* @author 孙辽东
* <p>createDate:2014年5月29日 上午11:51:22</p>
* @version V1.0
*/
public class Sha1KeyStrategy extends HashCodeKeyStrategy{
protected String
concatenateKey(String regionName, Object key){
String longKey =
super.concatenateKey(regionName, key);
return EncipherFactory.newInstance(EncipherEnum.SHA).encrypt(longKey);
}
}
StringKeyStrategy
package com.sunld.manager_core.tools.encipher.keystrategy;
/**
* @author 孙辽东
* <p>createDate:2014年5月29日 上午11:52:38</p>
* @version V1.0
*/
public class StringKeyStrategy extends AbstractKeyStrategy{
protected String
transformKeyObject(Object key){
String stringKey = String.valueOf(key);
if (LOGGER.isInfoEnabled())
LOGGER.info(
"Transformed key [{" + key +
"}] to string [{" + stringKey +
"}]");
return stringKey;
}
}