使用工厂模式、策略模式实现BASE64,MD5,SHA,HMAC,DES各种加密算法
2017-07-24 00:00
671 查看
定义枚举类型,包含已经集成的加密算法
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");//防止中文乱码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){ // 创建一个空的8位字节数组(默认值为0) byte[] arrB = new byte[8]; // 将原始字节数组转换为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; } }
相关文章推荐
- 使用工厂模式、策略模式实现BASE64,MD5,SHA,HMAC,DES各种加密算法
- BASE64、MD5、SHA、HMAC几种加密算法
- 加密算法中BASE64、MD5、SHA、HMAC等之间的区别
- 【JAVA】常用加解密算法总结及JAVA实现【BASE64,MD5,SHA,DES,3DES,AES,RSA】
- 加密算法中BASE64、MD5、SHA、HMAC等之间的区别
- [C#] 简单的 Helper 封装 -- SecurityHelper 安全助手:封装加密算法(MD5、SHA、HMAC、DES、RSA)
- BASE64、MD5、SHA、HMAC几种加密算法
- 介绍BASE64、MD5、SHA、HMAC几种加密算法
- C#封装加密算法(MD5、SHA、HMAC、DES、RSA)的一个类
- BASE64、MD5、SHA、HMAC几种加密算法
- 本篇内容简要介绍BASE64、MD5、SHA、HMAC几种加密算法。
- BASE64、MD5、SHA、HMAC几种加密算法(转)
- BASE64、MD5、SHA、HMAC几种加密算法
- 加密算法中BASE64、MD5、SHA、HMAC等之间的区别
- BASE64、MD5、SHA、HMAC几种加密算法
- commons-codec中[md5,sha,base64加密算法]的实现demo
- 简单的 Helper 封装 -- SecurityHelper 安全助手:封装加密算法(MD5、SHA、HMAC、DES、RSA)
- 单向加密算法-BASE64、MD5、SHA、HMAC
- BASE64及单向加密算法--(MD5、SHA、HMAC)介绍