使用工厂模式、策略模式实现BASE64,MD5,SHA,HMAC,DES各种加密算法

释放双眼,带上耳机,听听看~!

定义枚举类型,包含已经集成的加密算法


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

给TA打赏
共{{data.count}}人
人已打赏
安全技术安全运维

Windows服务器如何发现被黑

2018-5-20 12:24:31

安全技术

详解Node.js API系列 Http模块(1) 构造一个简单的静态页服务器

2021-12-21 16:36:11

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索