Java加密技术(Jasypt、MD5、AES)

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;
    }
}
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值