Java加密技术(Jasypt、MD5、AES)
程序员文章站
2024-03-16 20:07:34
...
java加解密算法有很多,在此记录常用的三种Jasypt、MD5、AES加密算法的使用;
(1) Jasypt
- Jasypt 加密, 通常用于加密配置文件中的密码,比如mysql密码、redis密码等;
<!-- jasypt 加解密-->
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>2.1.1</version>
</dependency>
配置:
# 加密的盐
jasypt:
encryptor:
password: qwetqweyiquq
# ENC(加密后的密文)
redis:
password: ENC(VPSapwY1AJzmHZQjWq62KpBiMDu7W37M)
测试代码:
@Test
public void testJasypt(){
BasicTextEncryptor textEncryptor = new BasicTextEncryptor();
//加密所需的salt(盐)
textEncryptor.setPassword("qwetqweyiquq");
//要加密的数据(数据库的用户名或密码)
String username = textEncryptor.encrypt("root");
String password = textEncryptor.encrypt("123456");
System.out.println("username:" + username);
System.out.println("password:" + password);
// 解密
String realUsername = textEncryptor.decrypt(username);
String realPassword = textEncryptor.decrypt(password);
System.out.println("realUsername:" + realUsername);
System.out.println("realPassword:" + realPassword);
}
(2)MD5 加密算法
-
MD5 是一种单向加密算法,只能加密不能解密。
-
常用于用户登录密码的加密。
-
防止被在线解密方案:可以在得到MD5加密后的密文进行进一步处理,如截取前16位保存后16位用随机码补充,不允许设置简单密码等。
import java.io.File;
import java.io.FileInputStream;
import java.math.BigInteger;
import java.security.MessageDigest;
/**
* MD5加密工具类
* @author cxq
* @date 2021/6/25
*/
public class MD5Util {
//用来将字节转换成16进制表示的字符
private static char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6',
'7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
/**
* 私有构造函数,防止实例化使用
*/
private MD5Util() {}
/**
* 对参数进行MD5加密
* @param bytes 要加密的参数
* @return MD5值
*/
public static String getMD5(byte[] bytes) {
String result = null;
MessageDigest md = null;
try {
md = MessageDigest.getInstance("MD5");
md.update(bytes);
byte[] temp = md.digest(); //MD5的计算结果是一个128位长整数,用字节表示就是16字节
char[] chars = new char[32]; //每个字节用16进制表示的话,需要2个字符,所以共32个字符
//对MD5的每个字节转换成16进制的字符
int k = 0;
for (int i = 0; i < 16; i++) {
byte aByte = temp[i];
chars[k++] = hexDigits[aByte >>> 4 & 0xf];
chars[k++] = hexDigits[aByte & 0xf];
}
result = new String(chars);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 对参数进行MD5加密
* @param str 要加密的参数
* @return MD5值
*/
public static String getMD5(String str) {
return getMD5(str.getBytes());
}
/**
* 计算文件的MD5加密值,注意如果文件较大、计算MD5时可能性能较差
* @param file 文件
* @return MD5值
*/
public static String getFileMD5(File file) {
FileInputStream in = null;
String result = null;
try {
MessageDigest md = MessageDigest.getInstance("MD5");
in = new FileInputStream(file);
byte[] buffer = new byte[1024];
while (in.read(buffer) != -1) {
md.update(buffer);
}
BigInteger bigInt = new BigInteger(1, md.digest());
result = bigInt.toString(16);
} catch (Exception e) {
throw new RuntimeException("MD5加密异常");
} finally {
try {
if (in != null) {
in.close();
}
} catch (Exception e) {
throw new RuntimeException("MD5加密时,流关闭异常");
}
}
return result;
}
/**
* 计算文件的MD5加密值
* @param fileName 文件名
* @return MD5值
*/
public static String getFileMD5(String fileName) {
File file = new File(fileName);
return getFileMD5(file);
}
public static void main(String[] arg){
String md5 = getMD5("111111");
System.out.println(md5);
}
}
(3)AES 对称加解密算法
- AES高级加密标准,是一种区块加密标准。这个标准用来替代原先的DES,比DES安全级别高,已经被多方分析且广为全世界所使用。
- AES加密算法,速度快,安全级别高:目前是最安全的加密算法之一。
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
/**
* AES 加密工具类
* @author cxq
* @date 2021/6/25
*/
public class AESUtil {
//自己定义的秘钥,128bit即16位的随机串。也支持192,25bit,长度越长安全性越高,对应的加解密时间越长
private final static String KEY_STR = "gOZ+l59TRoBajn3G";// 可以写进配置
private final Key key;
private static AESUtil instance = new AESUtil();
private static final String ALGORITHM = "AES";
private static final String RANDOM_ALGORITHM = "SHA1PRNG";
/**
* 私有构造函数,防止通过实例化使用
*/
private AESUtil() {
try {
KeyGenerator generator = KeyGenerator.getInstance(ALGORITHM);//Java的秘钥生产器,使用的是AES
SecureRandom random = SecureRandom.getInstance(RANDOM_ALGORITHM);//随机数的算法,NativePRNG和SHA1PRNG
random.setSeed(KEY_STR.getBytes());//用我们设定的秘钥串作为随机数的种子,因为种子是我们固定的,产生的随机数也是固定的
generator.init(random);
key = generator.generateKey();//生成的秘钥,我们在加密解密需要用到相同秘钥
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("AES构造函数异常");
}
}
public static AESUtil getInstance() {
return instance;
}
/**
* 对byte[]参数进行加密
* @param bytes 要加密的参数
* @return 加密后的参数
*/
private byte[] getEncCode(byte[] bytes) {
byte[] result = null;
Cipher cipher = null;
try {
cipher = Cipher.getInstance("AES");//获取算法实例
cipher.init(Cipher.ENCRYPT_MODE, key);//初始化,入参为加密模式和秘钥
result = cipher.doFinal(bytes);//进行加密
} catch (Exception e) {
throw new RuntimeException("AES加密异常");
} finally {
cipher = null;
}
return result;
}
/**
* 对byte[]参数进行解密
* @param bytes 要解密的参数
* @return 解密后的参数
*/
private byte[] getDesCode(byte[] bytes) {
byte[] result = null;
Cipher cipher = null;
try {
cipher = Cipher.getInstance("AES");//获取算法实例
cipher.init(Cipher.DECRYPT_MODE, key);//初始化,入参为解密模式和秘钥
result = cipher.doFinal(bytes);//进行解密
} catch (Exception e) {
throw new RuntimeException("AES解密异常");
} finally {
cipher = null;
}
return result;
}
/**
* 对string参数进行加密
* @param str 要加密的参数
* @return 加密后的参数
*/
public String getEncString(String str) {
BASE64Encoder base64en = new BASE64Encoder();
byte[] input = null; //明文
byte[] output = null; //密文
String result = null;
try {
input = str.getBytes();
output = getEncCode(input);
result = base64en.encode(output);
} catch (Exception e) {
throw new RuntimeException("AES解密异常,参数:" + str);
} finally {
input = null;
output = null;
}
return result;
}
/**
* 对String参数进行解密
* @param str 要解密的参数
* @return 解密后的参数
*/
public String getDesString(String str) {
BASE64Decoder base64De = new BASE64Decoder();
byte[] input = null; //密文
byte[] output = null; //明文
String result = null;
try {
input = base64De.decodeBuffer(str);
output = getDesCode(input);
result = new String(output);
} catch (Exception e) {
throw new RuntimeException("AES解密异常,参数:" + str);
} finally {
input = null;
output = null;
}
return result;
}
}