package com.hbbc.util;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
/**
* 加解密工具集。
* 需要导入:commons-codec-1.10.jar 包。这个是apache的工具包。
*/
public class EncryptUtil {
/**
* MD5摘要加密
* eg: System.out.println(EncryptUtil.md5Encrypt("hello world!"));
*
* @param str 原始字符串
* @return 加密后的字符串
*/
public static String md5Encrypt(String str){
String returnStr = DigestUtils.md5Hex(str);
return DigestUtils.md5Hex(returnStr);
}
/**
* 对字符串做BASE64编码
* eg: System.out.println(EncryptUtil.base64Encrypt("hello world! +-* / 中文"));
*
* @param str 原始字符串
* @return 编码后的字符串
*/
public static String base64Encrypt(String str){
byte[] b=str.getBytes();
Base64 base64=new Base64();
b=base64.encode(b);
String s=new String(b);
return s;
}
/**
* 对byte[] 数组做base64 编码
* eg: byte[] barr = IOUtil.readBinFile("d:/temp/b.jpg");
* System.out.println(EncryptUtil.base64ByteEncrypt(barr));
*
* @param data byte[]数组
* @return 编码后的字符串
*/
public static String base64ByteEncrypt(byte[] data){
Base64 base64=new Base64();
data=base64.encode(data);
String s=new String(data);
return s;
}
/**
* 对字符串做BASE64解码
* eg: System.out.println(EncryptUtil.base64Decrypt(EncryptUtil.base64Encrypt("hello world! +-* / 中文")));
*
* @param str 编码后的字符串
* @return 解码后的字符串
*/
public static String base64Decrypt(String str){
byte[] b=str.getBytes();
Base64 base64=new Base64();
b=base64.decode(b);
String s=new String(b);
return s;
}
/**
* 对字符串做Base64解码,解成byte[] 数组。可以通过此种方式解决Base64解码后中文乱码问题。
* eg: byte[] barr = IOUtil.readBinFile("d:/temp/b.jpg");
* String jpgStr = EncryptUtil.base64ByteEncrypt(barr);
* IOUtil.writeBinFile("d:/temp/bb.jpg", EncryptUtil.base64ByteDecrypt(jpgStr));
* eg: String a = new String(EncryptUtil.base64ByteDecrypt("5oKo5aW977yMaGVsbG8gd29ybGQh"), "utf-8");
*
* @param str 编码后的字符串
* @return 解码后的byte数组
*/
public static byte[] base64ByteDecrypt(String str){
byte[] b=str.getBytes();
Base64 base64=new Base64();
b=base64.decode(b);
return b;
}
/**
* DES加密。对称加密算法,加密强度不高。一般现在计算机技术24小时左右可以破解。
* 加密后返回的是做了Base64编码后的字符串。若直接用new String()的方式来转化,会出问题!无法解密回去。
* eg: System.out.println(EncryptUtil.desEncrypt("helloworld您好,世界!^&*", "12345678"));
*
* @param plainStr 待加密的原始字符串
* @param key 密钥,一般需要大于8位,为空或不足8位,会容错自动补齐
* @return DES加密后并做了Base64编码后的字符串
*/
public static String desEncrypt(String plainStr, String key) {
try {
//若是密钥为Null或者不足8位,自动补齐8位
if(key==null) key = "hbbcfrom2014";
if(key.length()<8) key = key+"hbbcfrom2014";
//准备加密
Cipher cipher = Cipher.getInstance("DES");
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
DESKeySpec keySpec = new DESKeySpec(key.getBytes());
keyFactory.generateSecret(keySpec);
cipher.init(Cipher.ENCRYPT_MODE, keyFactory.generateSecret(keySpec));
// 为了防止解密时报javax.crypto.IllegalBlockSizeException: Input length
// must be multiple of 8 when decrypting with padded cipher异常
// 不能把加密后的字节数组直接转换成字符串,而应该是做Base64编码
byte[] buf = cipher.doFinal(plainStr.getBytes()); //加密
return new String((new Base64()).encode(buf)); //对结果进行Base64编码
} catch (Exception e) {
LogUtil.exception(e);
}
return null;
}
/**
* DES解密
* eg: String secretData = EncryptUtil.desEncrypt("helloworld您好,世界!^&*", "hehe");
* System.out.println(EncryptUtil.desDecrypt(secretData, "hehe"));
*
* @param secretStr DES加密,并做Base64编码后的字符串
* @param key 密钥,一般需要大于8位,为空或不足8位,会容错自动补齐
* @return 解密后的字符串
*/
public static String desDecrypt(String secretStr, String key) {
try {
//若是密钥为Null或者不足8位,自动补齐8位
if(key==null) key = "hbbcfrom2014";
if(key.length()<8) key = key+"hbbcfrom2014";
//准备解密
Cipher cipher = Cipher.getInstance("DES");
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
DESKeySpec keySpec = new DESKeySpec(key.getBytes());
keyFactory.generateSecret(keySpec);
SecretKey keyObj = keyFactory.generateSecret(keySpec);
cipher.init(Cipher.DECRYPT_MODE, keyObj);
//准备解密
byte[] b=(new Base64()).decode(secretStr.getBytes()); //Base64反序列化为数组
byte[] buf = cipher.doFinal(b); //解密
return new String(buf); //组织成字符串形式返回
} catch (Exception e) {
LogUtil.exception(e);
}
return null;
}
/**
* AES加密。对称加密算法,加密强度高。
* eg: System.out.println(EncryptUtil.aesEncrypt("中文加密字符串测试1234454yuuyu$%^&OK!", "haha"));
*
* @param plainStr 加密字符串
* @param key 加密密钥(算法要求必须是16位的,不足会自动补齐,超过会被截取成16位!)
* @return 加密后的字符串(做了Base64编码转换后的字符串)
*/
public static String aesEncrypt(String plainStr, String key) {
try {
//补齐数据,必须是16位的整数!
if(plainStr==null) plainStr="";
byte[] strArr = plainStr.getBytes();
byte[] newStrArr = new byte[(strArr.length/16+1)*16];
for(int b=0; b<strArr.length; b++){ newStrArr[b] = strArr[b]; }
//补齐密钥,必须是16位
if(key==null) {
key="hbbc2014hbbc2014";
}else{
key = key+"hbbc2014hbbc2014";
}
byte[] keyArr = key.getBytes();
byte[] newKeyArr = new byte[16];
for(int k=0; k<16; k++){ newKeyArr[k] = keyArr[k]; }
//开始加密
SecretKeySpec keyObj = new SecretKeySpec(newKeyArr, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, keyObj); // 初始化
byte[] result = cipher.doFinal(newStrArr); // 加密
return new String((new Base64()).encode(result)); //对结果进行Base64编码
} catch (Exception e) {
LogUtil.exception(e);
}
return null;
}
/**
* AES解密
* eg: String encryptStr = EncryptUtil.aesEncrypt("中