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