1.引入依賴
<!-- 加密工具包 包含MD5襟锐、RSA钢拧、AES等加密方式-->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
AES加焙贷、解密算法工具類
package pers.darcy.flower.utils.util;
import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
/**
* AES加楞抡、解密算法工具類
*/
public class AESUtil {
/**
* 加密算法AES
*/
private static final String KEY_ALGORITHM = "AES";
/**
* key的長(zhǎng)度,Wrong key size: must be equal to 128, 192 or 256
* 傳入時(shí)需要16、24、36
*/
private static final Integer KEY_LENGTH = 16 * 8;
/**
* 算法名稱/加密模式/數(shù)據(jù)填充方式
* 默認(rèn):AES/ECB/PKCS5Padding
*/
private static final String ALGORITHMS = "AES/ECB/PKCS5Padding";
/**
* 后端AES的key,由靜態(tài)代碼塊賦值
*/
public static String key;
static {
key = getKey();
}
/**
* 獲取key
*/
public static String getKey() {
StringBuilder uid = new StringBuilder();
//產(chǎn)生16位的強(qiáng)隨機(jī)數(shù)
Random rd = new SecureRandom();
for (int i = 0; i < KEY_LENGTH / 8; i++) {
//產(chǎn)生0-2的3位隨機(jī)數(shù)
int type = rd.nextInt(3);
switch (type) {
case 0:
//0-9的隨機(jī)數(shù)
uid.append(rd.nextInt(10));
break;
case 1:
//ASCII在65-90之間為大寫,獲取大寫隨機(jī)
uid.append((char) (rd.nextInt(25) + 65));
break;
case 2:
//ASCII在97-122之間為小寫颅筋,獲取小寫隨機(jī)
uid.append((char) (rd.nextInt(25) + 97));
break;
default:
break;
}
}
return uid.toString();
}
/**
* 加密
*
* @param content 加密的字符串
* @param encryptKey key值
*/
public static String encrypt(String content, String encryptKey) throws Exception {
//設(shè)置Cipher對(duì)象
Cipher cipher = Cipher.getInstance(ALGORITHMS,new BouncyCastleProvider());
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(encryptKey.getBytes(), KEY_ALGORITHM));
//調(diào)用doFinal
byte[] b = cipher.doFinal(content.getBytes(StandardCharsets.UTF_8));
// 轉(zhuǎn)base64
return Base64.encodeBase64String(b);
}
/**
* 解密
*
* @param encryptStr 解密的字符串
* @param decryptKey 解密的key值
*/
public static String decrypt(String encryptStr, String decryptKey) throws Exception {
//base64格式的key字符串轉(zhuǎn)byte
byte[] decodeBase64 = Base64.decodeBase64(encryptStr);
//設(shè)置Cipher對(duì)象
Cipher cipher = Cipher.getInstance(ALGORITHMS,new BouncyCastleProvider());
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(decryptKey.getBytes(), KEY_ALGORITHM));
//調(diào)用doFinal解密
byte[] decryptBytes = cipher.doFinal(decodeBase64);
return new String(decryptBytes);
}
// public static void main(String[] args) {
// //16位
// String key = "MIGfMA0GCSqGSIb3";
//
// //字符串
// String str = "huanzi.qch@qq.com:歡子";
// try {
// //加密
// String encrypt = AESUtil.encrypt(str, key);
// //解密
// String decrypt = AESUtil.decrypt(encrypt, key);
// System.out.println("加密前:" + str);
// System.out.println("加密后:" + encrypt);
// System.out.println("解密后:" + decrypt);
// } catch (Exception e) {
// e.printStackTrace();
// }
// }
public static void main(String[] args) {
//16位
String key = "MIGfMA0GCSqGSIb3";
//復(fù)雜對(duì)象
Map<String,Object> userMap = new HashMap<>(2);
userMap.put("username","123456");
userMap.put("password","111111");
try {
//加密
String encrypt = AESUtil.encrypt(userMap.toString(), key);
//解密
String decrypt = AESUtil.decrypt(encrypt, key);
System.out.println("加密前:" + userMap.toString());
System.out.println("加密后:" + encrypt);
System.out.println("解密后:" + decrypt);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Base64加密解密 工具類
package pers.darcy.flower.utils.util;
import org.apache.commons.codec.binary.Base64;
/**
* Base64加密解密 工具類
*
* @author wbw
* @version 1.0
* @since 1.0
*/
public abstract class Base64Util {
/**
* 字符編碼
*/
private final static String ENCODING = "UTF-8";
/**
* 方法描述: Base64編碼
*
* @param data 待編碼數(shù)據(jù)
* @return java.lang.String
* @author wqf
* @date 2022/1/19 11:54
*/
public static String encode(String data) throws Exception {
// 執(zhí)行編碼
byte[] b = Base64.encodeBase64(data.getBytes(ENCODING));
return new String(b, ENCODING);
}
/**
* 方法描述: Base64安全編碼<br>
* 遵循RFC 2045實(shí)現(xiàn)
*
* @param data 待編碼數(shù)據(jù)
* @return java.lang.String
* @author wqf
* @date 2022/1/19 11:53
*/
public static String encodeSafe(String data) throws Exception {
// 執(zhí)行編碼
byte[] b = Base64.encodeBase64(data.getBytes(ENCODING), true);
return new String(b, ENCODING);
}
/**
* 方法描述: Base64解碼
*
* @param data 待解碼數(shù)據(jù)
* @return java.lang.String
* @author wqf
* @date 2022/1/19 11:53
*/
public static String decode(String data) throws Exception {
// 執(zhí)行解碼
byte[] b = Base64.decodeBase64(data.getBytes(ENCODING));
return new String(b, ENCODING);
}
}
DES工具類
package pers.darcy.flower.utils.util;
import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import java.security.Key;
import java.security.SecureRandom;
import java.security.Security;
/**
* DES安全編碼組件
*
* @author wbw
* @version 1.0
*/
public abstract class DESUtil {
static {
Security.insertProviderAt(new BouncyCastleProvider(), 1);
}
//new BouncyCastleProvider();后端加解密中,不能在代碼里new BouncyCastleProvider()输枯,JceSecurity. getVerificationResult內(nèi)部會(huì)進(jìn)行判斷议泵,如果是新值,則每次都會(huì)put到map中桃熄,導(dǎo)致內(nèi)存緩便被耗盡先口,程序假死崩潰
// private static final BouncyCastleProvider BOUNCY_CASTLE_PROVIDER=new BouncyCastleProvider();
/**
* 密鑰算法 <br>
* Java 6 只支持56bit密鑰 <br>
* Bouncy Castle 支持64bit密鑰
*/
private static final String KEY_ALGORITHM = "DES";
/**
* 加密/解密算法 / 工作模式 / 填充方式
*/
private static final String CIPHER_ALGORITHM = "DES/ECB/PKCS5PADDING";
/**
* 轉(zhuǎn)換密鑰
*
* @param key 二進(jìn)制密鑰
* @return Key 密鑰
* @throws Exception
*/
private static Key toKey(byte[] key) throws Exception {
// 實(shí)例化DES密鑰材料
DESKeySpec dks = new DESKeySpec(key);
// 實(shí)例化秘密密鑰工廠
SecretKeyFactory keyFactory = SecretKeyFactory
.getInstance(KEY_ALGORITHM);
// 生成秘密密鑰
return keyFactory.generateSecret(dks);
}
/**
* 方法描述: 解密
*
* @param data 待解密數(shù)據(jù)
* @param key 密鑰
* @return byte[]
* @author wqf
* @date 2022/1/19 14:03
*/
public static byte[] decrypt(byte[] data, byte[] key) throws Exception {
// 還原密鑰
Key k = toKey(key);
// 實(shí)例化
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
// 初始化,設(shè)置為解密模式
cipher.init(Cipher.DECRYPT_MODE, k);
// 執(zhí)行操作
return cipher.doFinal(data);
}
/**
* 方法描述: 加密
*
* @param data 待加密數(shù)據(jù)
* @param key 密鑰
* @return byte[]
* @author wqf
* @date 2022/1/19 14:03
*/
public static byte[] encrypt(byte[] data, byte[] key) throws Exception {
// 還原密鑰
Key k = toKey(key);
// 實(shí)例化
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
// 初始化瞳收,設(shè)置為加密模式
cipher.init(Cipher.ENCRYPT_MODE, k);
// 執(zhí)行操作
return cipher.doFinal(data);
}
/**
* 方法描述: 生成密鑰
*
* @return byte[]
* @author wqf
* @date 2022/1/19 14:03
*/
public static byte[] initKey() throws Exception {
//實(shí)例化密鑰生成器碉京,若要使用64bit密鑰注意替換 將下述代碼中的KeyGenerator.getInstance(CIPHER_ALGORITHM);替換為KeyGenerator.getInstance(CIPHER_ALGORITHM, "BC");
KeyGenerator kg = KeyGenerator.getInstance(KEY_ALGORITHM);
//初始化密鑰生成器 若要使用64bit密鑰注意替換 將下述代碼kg.init(56); 替換為kg.init(64);
kg.init(56, new SecureRandom());
// 生成秘密密鑰
SecretKey secretKey = kg.generateKey();
// 獲得密鑰的二進(jìn)制編碼形式
return secretKey.getEncoded();
}
public static byte[] initKey(String seed) throws Exception {
KeyGenerator kg = KeyGenerator.getInstance(KEY_ALGORITHM);
SecureRandom secureRandom = new SecureRandom(new Base64().decode(seed));
kg.init(secureRandom);
SecretKey secretKey = kg.generateKey();
return secretKey.getEncoded();
}
}
MD5工具類
package pers.darcy.flower.utils.util;
import org.apache.commons.codec.digest.DigestUtils;
/**
* MD5加密組件
*
* @author wbw
* @version 1.0
* @since 1.0
*/
public abstract class MD5Util {
/**
* 方法描述: MD5加密
*
* @param data 待加密數(shù)據(jù)
* @return byte[]
* @author wqf
* @date 2022/1/19 11:54
*/
public static byte[] encodeMD5(String data) throws Exception {
// 執(zhí)行消息摘要
return DigestUtils.md5(data);
}
/**
* 方法描述: MD5加密
*
* @param data 待加密數(shù)據(jù)
* @return java.lang.String
* @author wqf
* @date 2022/1/19 11:54
*/
public static String encodeMD5Hex(String data) {
// 執(zhí)行消息摘要
return DigestUtils.md5Hex(data);
}
}
RSA加、解密算法工具類
package cn.huanzi.ims.util;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
/**
* RSA加螟深、解密算法工具類
*/
public class RSAUtil {
/**
* 加密算法AES
*/
private static final String KEY_ALGORITHM = "RSA";
/**
* 算法名稱/加密模式/數(shù)據(jù)填充方式
* 默認(rèn):RSA/ECB/PKCS1Padding
*/
private static final String ALGORITHMS = "RSA/ECB/PKCS1Padding";
/**
* Map獲取公鑰的key
*/
private static final String PUBLIC_KEY = "publicKey";
/**
* Map獲取私鑰的key
*/
private static final String PRIVATE_KEY = "privateKey";
/**
* RSA最大加密明文大小
*/
private static final int MAX_ENCRYPT_BLOCK = 117;
/**
* RSA最大解密密文大小
*/
private static final int MAX_DECRYPT_BLOCK = 128;
/**
* RSA 位數(shù) 如果采用2048 上面最大加密和最大解密則須填寫: 245 256
*/
private static final int INITIALIZE_LENGTH = 1024;
/**
* 后端RSA的密鑰對(duì)(公鑰和私鑰)Map谐宙,由靜態(tài)代碼塊賦值
*/
private static Map<String, Object> genKeyPair = new HashMap<>();
static {
try {
genKeyPair.putAll(genKeyPair());
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 生成密鑰對(duì)(公鑰和私鑰)
*/
private static Map<String, Object> genKeyPair() throws Exception {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
keyPairGen.initialize(INITIALIZE_LENGTH);
KeyPair keyPair = keyPairGen.generateKeyPair();
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
Map<String, Object> keyMap = new HashMap<String, Object>(2);
//公鑰
keyMap.put(PUBLIC_KEY, publicKey);
//私鑰
keyMap.put(PRIVATE_KEY, privateKey);
return keyMap;
}
/**
* 私鑰解密
*
* @param encryptedData 已加密數(shù)據(jù)
* @param privateKey 私鑰(BASE64編碼)
*/
public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey) throws Exception {
//base64格式的key字符串轉(zhuǎn)Key對(duì)象
byte[] keyBytes = Base64.decodeBase64(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
//設(shè)置加密、填充方式
/*
如需使用更多加密界弧、填充方式凡蜻,引入
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<version>1.46</version>
</dependency>
并改成
Cipher cipher = Cipher.getInstance(ALGORITHMS ,new BouncyCastleProvider());
*/
Cipher cipher = Cipher.getInstance(ALGORITHMS);
cipher.init(Cipher.DECRYPT_MODE, privateK);
//分段進(jìn)行解密操作
return encryptAndDecryptOfSubsection(encryptedData, cipher, MAX_DECRYPT_BLOCK);
}
/**
* 公鑰加密
*
* @param data 源數(shù)據(jù)
* @param publicKey 公鑰(BASE64編碼)
*/
public static byte[] encryptByPublicKey(byte[] data, String publicKey) throws Exception {
//base64格式的key字符串轉(zhuǎn)Key對(duì)象
byte[] keyBytes = Base64.decodeBase64(publicKey);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key publicK = keyFactory.generatePublic(x509KeySpec);
//設(shè)置加密、填充方式
/*
如需使用更多加密垢箕、填充方式划栓,引入
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<version>1.46</version>
</dependency>
并改成
Cipher cipher = Cipher.getInstance(ALGORITHMS ,new BouncyCastleProvider());
*/
Cipher cipher = Cipher.getInstance(ALGORITHMS);
cipher.init(Cipher.ENCRYPT_MODE, publicK);
//分段進(jìn)行加密操作
return encryptAndDecryptOfSubsection(data, cipher, MAX_ENCRYPT_BLOCK);
}
/**
* 獲取私鑰
*/
public static String getPrivateKey() {
Key key = (Key) genKeyPair.get(PRIVATE_KEY);
return Base64.encodeBase64String(key.getEncoded());
}
/**
* 獲取公鑰
*/
public static String getPublicKey() {
Key key = (Key) genKeyPair.get(PUBLIC_KEY);
return Base64.encodeBase64String(key.getEncoded());
}
/**
* 分段進(jìn)行加密、解密操作
*/
private static byte[] encryptAndDecryptOfSubsection(byte[] data, Cipher cipher, int encryptBlock) throws Exception {
int inputLen = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 對(duì)數(shù)據(jù)分段加密
while (inputLen - offSet > 0) {
if (inputLen - offSet > encryptBlock) {
cache = cipher.doFinal(data, offSet, encryptBlock);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * encryptBlock;
}
byte[] toByteArray = out.toByteArray();
out.close();
return toByteArray;
}
//
// public static void main(String[] args) {
// //字符串
// String str = "huanzi.qch@qq.com:歡子";
// try {
// System.out.println("私鑰:" + RSAUtil.getPrivateKey());
// System.out.println("公鑰:" + RSAUtil.getPublicKey());
//
// //公鑰加密
// byte[] ciphertext = RSAUtil.encryptByPublicKey(str.getBytes(), RSAUtil.getPublicKey());
// //私鑰解密
// byte[] plaintext = RSAUtil.decryptByPrivateKey(ciphertext, RSAUtil.getPrivateKey());
//
// System.out.println("公鑰加密前:" + str);
// System.out.println("公鑰加密后:" + Base64.encodeBase64String(ciphertext));
// System.out.println("私鑰解密后:" + new String(plaintext));
// } catch (Exception e) {
// e.printStackTrace();
// }
// }
public static void main(String[] args) {
//復(fù)雜對(duì)象
Map<String,Object> userMap = new HashMap<>(2);
userMap.put("username","123456");
userMap.put("password","111111");
try {
System.out.println("私鑰:" + RSAUtil.getPrivateKey());
System.out.println("公鑰:" + RSAUtil.getPublicKey());
//公鑰加密
byte[] ciphertext = RSAUtil.encryptByPublicKey(userMap.toString().getBytes(), RSAUtil.getPublicKey());
//私鑰解密
byte[] plaintext = RSAUtil.decryptByPrivateKey(ciphertext, RSAUtil.getPrivateKey());
System.out.println("公鑰加密前:" + userMap.toString());
System.out.println("公鑰加密后:" + Base64.encodeBase64String(ciphertext));
System.out.println("私鑰解密后:" + new String(plaintext));
} catch (Exception e) {
e.printStackTrace();
}
}
}