做项目时或许要用到字符串的加密或解密,加密传输,密码存储等,
工具类的主要功能:
序号 | 加解密类型 | 参数 | 结果 |
---|---|---|---|
1 | MD5加密 | “12345” | 827ccb0eea8a706c4 c34a16891f84e7b |
2 | SHA1加密 | “12345” | 8cb2237d0679ca88db6 464eac60da96345513964 |
3 | 异或加密 | “12345” | бвгде |
异或解密 | <密文> | 12345 | |
自定义公钥异或加密 | “12345”, EncryptUtils.KEY_2 |
⪏⪌⪍⪊⪋ | |
自定义公钥异或解密 | <密文>, EncryptUtils.KEY_2 |
12345 | |
4 | base64加密 | “12345” | mwxPPdd/Ui8NzBw 85IcHq/ulKlKYcSmS |
base64解密 | <密文> | 12345 | |
5 | ASE加密 | “12345” | BD6F81A61A945E7 D834891811315271D |
ASE解密 | <密文> | 12345 |
代码:
EncryptRes.java
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
import java.util.Base64;
public class EncryptRes {
public static final int KEY_1 = 409821;
public static final int KEY_2 = 10942;
public static final int KEY_3 = 876430;
public static final String ASE_DUFAULT = "@ASE%->@666";
public static String key = "LmMGStGtOpF4xNyvYt54EQ==";
protected static byte[] MD5Hash(byte[] buf, int offset, int length)
throws Exception {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(buf, offset, length);
return md.digest();
}
protected static byte[] addMD5(byte[] md5Byte, byte[] bodyByte) {
int length = bodyByte.length + md5Byte.length;
byte[] resutlByte = new byte[length];
// 前16位放MD5Hash码
for (int i = 0; i < length; i++) {
if (i < md5Byte.length) {
resutlByte[i] = md5Byte[i];
} else {
resutlByte[i] = bodyByte[i - md5Byte.length];
}
}
return resutlByte;
}
protected static byte[] DES_CBC_Encrypt(byte[] sourceBuf, SecretKeySpec deskey, IvParameterSpec ivParam) throws Exception {
byte[] cipherByte;
// 使用DES对称加密算法的CBC模式加密
Cipher encrypt = Cipher.getInstance("DES/CBC/PKCS5Padding");
encrypt.init(Cipher.ENCRYPT_MODE, deskey, ivParam);
cipherByte = encrypt.doFinal(sourceBuf, 0, sourceBuf.length);
// 返回加密后的字节数组
return cipherByte;
}
protected static void getKeyIV(String encryptKey, byte[] key, byte[] iv) {
// 密钥Base64解密
Base64.Decoder decoder = Base64.getDecoder();
byte[] buf = null;
buf = decoder.decode(encryptKey);
// 前8位为key
int i;
for (i = 0; i < key.length; i++) {
key[i] = buf[i];
}
// 后8位为iv向量
for (i = 0; i < iv.length; i++) {
iv[i] = buf[i + 8];
}
}
protected static byte[] DES_CBC_Decrypt(byte[] sourceBuf, SecretKeySpec deskey, IvParameterSpec ivParam) throws Exception {
byte[] cipherByte;
// 获得Cipher实例,使用CBC模式。
Cipher decrypt = Cipher.getInstance("DES/CBC/PKCS5Padding");
// 初始化加密实例,定义为解密功能,并传入密钥,偏转向量
decrypt.init(Cipher.DECRYPT_MODE, deskey, ivParam);
cipherByte = decrypt.doFinal(sourceBuf, 0, sourceBuf.length);
// 返回解密后的字节数组
return cipherByte;
}
//十六进制转换二进制
public static byte[] parseHexStr2Byte(String hexStr) {
if (hexStr.length() < 1)
return null;
byte[] result = new byte[hexStr.length() / 2];
for (int i = 0; i < hexStr.length() / 2; i++) {
int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
result[i] = (byte) (high * 16 + low);
}
return result;
}
//二进制转换十六进制
public static String parseByte2HexStr(byte buf[]) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < buf.length; i++) {
String hex = Integer.toHexString(buf[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
sb.append(hex.toUpperCase());
}
return sb.toString();
}
}
EncryptUtils.java
import org.springframework.util.Base64Utils;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.util.Base64;
/**
* ClassName : EncryptUtils
* Param : com.osc.itheima_travel1.utils
* Create by Acachi-Akari
* CreateDatetime : 2019/2/16 8:23
* Description : 加密解密工具类
**/
public class EncryptUtils extends EncryptRes{
/**
* 对给定的字符使用md5进行加密,返回加密以后的字符串
*
* @param origin 要加密的字符串
* @return 返回加密过的字符串
*/
public static String getMd5(String origin) {
// 1) 使用静态方法,创建MessageDigest对象
try {
MessageDigest md = MessageDigest.getInstance("MD5");
// 2) 将字符串使用utf-8进行编码,得到字节数组
byte[] input = origin.getBytes("utf-8");
// 3) 使用digest(input)对字节数组进行md5的哈希计算,得到加密以后的字节数组,长度是16个字节。
byte[] num = md.digest(input);
// 4) 使用类BigInteger(1, 加密后的字节数组),将这个二进制数组转成无符号的大整数
// 1 正数, -1表示负数
BigInteger big = new BigInteger(1, num);
// 5) 将这个大整数转成16进制字符串,参数为多少进制
return big.toString(16);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
/**
* SHA1加密 , 安全性最高 , 不可逆算法
* @param str 需要加密的字符串
* @return
*/
public static String getSha1(String str){
if(str==null||str.length()==0){
return "";
}
char hexDigits[] = {'0','1','2','3','4','5','6','7','8','9',
'a','b','c','d','e','f'};
try {
MessageDigest mdTemp = MessageDigest.getInstance("SHA1");
mdTemp.update(str.getBytes("UTF-8"));
byte[] md = mdTemp.digest();
int j = md.length;
char buf[] = new char[j*2];
int k = 0;
for (int i = 0; i < j; i++) {
byte byte0 = md[i];
buf[k++] = hexDigits[byte0 >>> 4 & 0xf];
buf[k++] = hexDigits[byte0 & 0xf];
}
return new String(buf);
} catch (Exception e) {
return null;
}
}
/**
* 异或运算加解密
* @param str 需要加密或者需要解密的字符串
* @return
*/
public static String xorDEcrypt(String str) {
return xorDEcrypt(str, 1024);
}
/**
* 异或运算加解密
* @param str 需要加密或者需要解密的字符串
* @param key 公钥
* @return
*/
public static String xorDEcrypt(String str,int key) {
String res = "";
char[] c = str.toCharArray();
for(int i=0;i<c.length;i++) {
res += (char) (c[i]^key)+""; //^为异或符号,key默认设置1024
}
return res;
}
/**
* BASE64加密
* @param xmlStr 需要加密的字符串
* @return
*/
public static String base64Encrypt(String xmlStr) {
byte[] encrypt = null;
try {
// 取需要加密内容的utf-8编码。
encrypt = xmlStr.getBytes("utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
// 取MD5Hash码,并组合加密数组
byte[] md5Hasn = null;
try {
md5Hasn = MD5Hash(encrypt, 0, encrypt.length);
} catch (Exception e) {
e.printStackTrace();
}
// 组合消息体
byte[] totalByte = addMD5(md5Hasn, encrypt);
// 取密钥和偏转向量
byte[] key = new byte[8];
byte[] iv = new byte[8];
getKeyIV(EncryptUtils.key, key, iv);
SecretKeySpec deskey = new SecretKeySpec(key, "DES");
IvParameterSpec ivParam = new IvParameterSpec(iv);
// 使用DES算法使用加密消息体
byte[] temp = null;
try {
temp = DES_CBC_Encrypt(totalByte, deskey, ivParam);
} catch (Exception e) {
e.printStackTrace();
}
// 使用Base64加密后返回
return Base64Utils.encodeToString(temp);
}
/**
* BASE64解密
* @param xmlStr 需要解密的字符串
* @return
* @throws Exception
*/
public static String base64Decrypt(String xmlStr) throws Exception {
// base64解码
Base64.Decoder decoder = Base64.getDecoder();
byte[] encBuf = null;
try {
encBuf = decoder.decode(xmlStr);
} catch (Exception e) {
e.printStackTrace();
}
// 取密钥和偏转向量
byte[] key = new byte[8];
byte[] iv = new byte[8];
getKeyIV(EncryptUtils.key, key, iv);
SecretKeySpec deskey = new SecretKeySpec(key, "DES");
IvParameterSpec ivParam = new IvParameterSpec(iv);
// 使用DES算法解密
byte[] temp = null;
try {
temp = DES_CBC_Decrypt(encBuf, deskey, ivParam);
} catch (Exception e) {
e.printStackTrace();
}
// 进行解密后的md5Hash校验
byte[] md5Hash = null;
try {
md5Hash = MD5Hash(temp, 16, temp.length - 16);
} catch (Exception e) {
e.printStackTrace();
}
// 进行解密校检
for (int i = 0; i < md5Hash.length; i++) {
if (md5Hash[i] != temp[i]) {
// System.out.println(md5Hash[i] + "MD5校验错误。" + temp[i]);
throw new Exception("MD5校验错误。");
}
}
// 返回解密后的数组,其中前16位MD5Hash码要除去。
return new String(temp, 16, temp.length - 16, "utf-8");
}
/**
* 使用AES方式加密 - 使用默认方式
* @param content 加密内容
* @return 十六进制的密文
*/
public static String AseEncrypt(String content) {
return AseEncrypt(content,ASE_DUFAULT);
}
/**
* 使用AES方式解密 - 使用默认方式
* @param content 十六进制的密文
* @return 明文
*/
public static String AseDecrypt(String content) {
return AseDecrypt(content,ASE_DUFAULT);
}
/**
* 使用AES方式加密
* @param content 加密内容
* @param password 解密需要用到的钥匙
* @return 十六进制的密文
*/
public static String AseEncrypt(String content, String password) {
try {
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
random.setSeed(key.getBytes());
KeyGenerator kgen = KeyGenerator.getInstance("AES");
// 创建AES的Key生产者
kgen.init(128, random);// 利用用户密码作为随机数初始化出
// 128位的key生产者
//加密没关系,SecureRandom是生成安全随机数序列,password.getBytes()是种子,只要种子相同,序列就一样,所以解密只要有password就行
SecretKey secretKey = kgen.generateKey();// 根据用户密码,生成一个密钥
byte[] enCodeFormat = secretKey.getEncoded();// 返回基本编码格式的密钥,如果此密钥不支持编码,则返回
// null。
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");// 转换为AES专用密钥
Cipher cipher = Cipher.getInstance("AES");// 创建密码器
byte[] byteContent = content.getBytes("utf-8");
cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化为加密模式的密码器
byte[] result = cipher.doFinal(byteContent);// 加密
//返回十六进制的密文
return parseByte2HexStr(result);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 使用AES方式解密
* @param content 十六进制的密文
* @param password 解密需要用到的钥匙
* @return 明文
*/
public static String AseDecrypt(String content, String password) {
try {
//把十六进制的密文转换成二进制的密文
byte[] con = parseHexStr2Byte(content);
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
random.setSeed(key.getBytes());
KeyGenerator kgen = KeyGenerator.getInstance("AES");// 创建AES的Key生产者
kgen.init(128, random);
SecretKey secretKey = kgen.generateKey();// 根据用户密码,生成一个密钥
byte[] enCodeFormat = secretKey.getEncoded();// 返回基本编码格式的密钥
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");// 转换为AES专用密钥
Cipher cipher = Cipher.getInstance("AES");// 创建密码器
cipher.init(Cipher.DECRYPT_MODE, key);// 初始化为解密模式的密码器
byte[] result = cipher.doFinal(con);
return new String(result); // 明文
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
maven
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-coreartifactId>
<version>5.0.0.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-jdbcartifactId>
<version>5.0.0.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-txartifactId>
<version>5.0.0.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-beansartifactId>
<version>5.0.0.RELEASEversion>
dependency>