后端加密工具包(散列算法MD5、SHA带盐加密、AES对称加密)

使用示例:

@Service
public class DemoServiceImpl implements DemoService {
	@Autowired
	private EncryptUtil encryptUtil;
	@Autowired
	private VerifyCodeUtil verifyCodeUtil;
	@Value("${encryptUtil.password.algorithm}")
	private String passwordAlgorithm;
	@Value("${encryptUtil.password.salt}")
	private String passwordSalt;
	@Value("${encryptUtil.verifyCode.algorithm}")
	private String verifyCodeAlgorithm;
	
	public Boolean encryptDemo(String encryptedEmail) {
		//散列算法加密
		String password = "123456";
		String encrypted = encryptUtil.encryptWithSHA(password, passwordAlgorithm, passwordSalt);
		//AES解密
		String KEY = encryptUtil.getKeyOfAES();
		String VI = encryptUtil.getViReg();
		String email = encryptUtil.decryptWithAES(encryptedEmail, KEY, VI);
		return true;
	}
}

application.yml配置文件:

encryptUtil:
  tempSalt: efghijklaskodasoduvwx
  viToken: ABCDEF1261FEDCBA
  viReg: AADDEF8956FEDCFA
  password:
    algorithm: SHA-256
    salt: abcdeddlMt
  verifyCode:
    algorithm: SHA-256

工具包源码:

package com.xx.xx.utils;

import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.Random;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import lombok.Getter;

@Component
public class EncryptUtil {

    @Value("${encryptUtil.tempSalt}")
    private String tempSalt;
    @Getter
    @Value("${encryptUtil.viToken}")
    private String viToken; // AES的初始向量,可以通过手动更改VI控制Token的有效性
    @Getter
    @Value("${encryptUtil.viReg}")
    private String viReg; // 注册激活链接VI

    /**
     * 散列算法自带盐加密
     *
     * @param message   明文
     * @param algorithm 散列加密算法类型:MD2、MD5、SHA(SHA-1)、SHA-1、SHA-224、SHA-256、SHA-384、SHA-512等(不区分大小写)
     * @return String:密文
     * @throws NoSuchAlgorithmException
     */
    public String encryptWithSHA(String message, String algorithm) throws NoSuchAlgorithmException {
        // 密码盐值,防止使用彩虹表对密码进行爆破
        String salt;

        if (message.length() < 5) {
            salt = tempSalt;
        }
        salt = message.substring(0, 5);// 从序号0开始,截取5个字符长度

        String messageWithSalt = message + salt;

        // 生成实现指定摘要算法的MessageDigest对象
        MessageDigest md = MessageDigest.getInstance(algorithm);

        // 使用指定的字节数组对摘要进行最后更新,然后完成摘要计算
        byte[] digest = md.digest(messageWithSalt.getBytes(StandardCharsets.UTF_8));

        // 返回Base64字符串
        return Base64.getEncoder().encodeToString(digest);

//		md.update("123".getBytes("UTF-8")); // 使用指定的字节更新摘要
//		byte[] digest = md.digest(); // 通过执行诸如填充之类的最终操作完成哈希计算

        /* 进制转换 */
//		String outputstr = new BigInterger("str",10); // 实例化一个10进制的字符串
//		BigInteger bigInt = new BigInteger(1, digest); // 指定byte数组转换为正数BigInteger
//		bigInt.toString(16)//进行16进制转换

        /* Base64字符转换 */
//		byte[] decode = Base64.getDecoder().decode(str); // base64字符串转byte[]
//	    String encodeToString = Base64.getEncoder().encodeToString(byte[]); // byte[]转base64

    }

    public String getMd5Str(String message) throws NoSuchAlgorithmException {
    	String algorithm = "MD5";
        // 生成实现指定摘要算法的MessageDigest对象
        MessageDigest md = MessageDigest.getInstance(algorithm);

        // 使用指定的字节数组对摘要进行最后更新,然后完成摘要计算
        byte[] digest = md.digest(message.getBytes(StandardCharsets.UTF_8));

		return new BigInteger(1, digest).toString(10);
//				.substring(8, 24);
    }

    /**
     * 散列算法有盐加密
     *
     * @param message   明文
     * @param algorithm 散列加密算法类型:MD2、MD5、SHA(SHA-1)、SHA-1、SHA-224、SHA-256、SHA-384、SHA-512等(不区分大小写)
     * @param salt      密码盐值,防止使用彩虹表对密码进行爆破
     * @return
     * @throws NoSuchAlgorithmException
     */
    public String encryptWithSHA(String message, String algorithm, String salt)
            throws NoSuchAlgorithmException {
        String messageWithSalt = message + salt;

        // 生成实现指定摘要算法的MessageDigest对象
        MessageDigest md = MessageDigest.getInstance(algorithm);

        // 使用指定的字节数组对摘要进行最后更新,然后完成摘要计算
        byte[] digest = md.digest(messageWithSalt.getBytes(StandardCharsets.UTF_8));

        // 返回Base64字符串
        return Base64.getEncoder().encodeToString(digest);
    }

//	---------------------------------------------------------------------

    // 获取AES密钥(单例)--16位十六进制字符串
    private static String keyOfAES = null; // 静态变量赋初值只在函数第一次调用时起作用

    public String getKeyOfAES() {
        final int LENGTH = 16;

        // null表示这个字符串不指向任何的东西,如果这时候你调用它的方法,那么就会出现空指针异常。
        // ""表示它指向一个长度为0的字符串,这时候调用它的方法是安全的。
        // null不是对象,""是对象,所以null没有分配空间,""分配了空间
        // str.equals("");//str.isEmpty();//str.length() == 0
        if (keyOfAES == null || "".equals(keyOfAES)) {
            try {
                StringBuffer result = new StringBuffer();
                for (int i = 0; i < LENGTH; i++) {
                    result.append(Integer.toHexString(new Random().nextInt(16)));
                }
                keyOfAES = result.toString().toUpperCase();

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return keyOfAES;
    }

    /**
     * AES加密
     *
     * @param message 待加密信息
     * @param key     密钥
     * @return String:Base64编码字符串形式的密文
     */
    public String encryptWithAES(String message, String key, String vi) {
        final String ALGORITHM = "AES/CBC/PKCS5Padding";

        if (key == null || "".equals(key)) {
            return null;
        }
        if (key.length() != 16) {
            return null;
        }
        try {
            // 获取密钥
            byte[] raw = key.getBytes(); // 获得密码的字节数组
            SecretKeySpec skey = new SecretKeySpec(raw, "AES"); // 根据密码生成AES密钥

            // 初始化AES密码器
            Cipher cipher = Cipher.getInstance(ALGORITHM); // 根据指定算法ALGORITHM自成密码器
            cipher.init(Cipher.ENCRYPT_MODE, skey, new IvParameterSpec(vi.getBytes())); // 初始化密码器,第一个参数为加密(ENCRYPT_MODE)或者解密(DECRYPT_MODE)操作,第二个参数为生成的AES密钥

            // 加密
            byte[] byteMessage = message.getBytes(StandardCharsets.UTF_8); // 获取加密内容的字节数组(设置为utf-8)不然内容中如果有中文和英文混合中文就会解密为乱码
            byte[] encodeMessage = cipher.doFinal(byteMessage); // 密码器加密数据

            return Base64.getEncoder().encodeToString(encodeMessage); // 将加密后的数据转换为Base64编码字符串返回
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * AES解密
     *
     * @param message Base64编码字符串的密文
     * @param key     密钥
     * @return String:明文
     */
    public String decryptWithAES(String message, String key, String vi) {
        final String ALGORITHM = "AES/CBC/PKCS5Padding";

        if (message == null || "".equals(message)) {
            return null;
        }

        if (key == null || "".equals(key)) {
            return null;
        }
        if (key.length() != 16) {
            return null;
        }
        try {
            // 获取密钥
            byte[] raw = key.getBytes(); // 获得密码的字节数组
            SecretKeySpec skey = new SecretKeySpec(raw, "AES"); // 根据密码生成AES密钥

            // 初始化AES密码器
            Cipher cipher = Cipher.getInstance(ALGORITHM); // 根据指定算法ALGORITHM自成密码器
            cipher.init(Cipher.DECRYPT_MODE, skey, new IvParameterSpec(vi.getBytes())); // 初始化密码器,第一个参数为加密(ENCRYPT_MODE)或者解密(DECRYPT_MODE)操作,第二个参数为生成的AES密钥

            // 解密
            byte[] encodeMessage = Base64.getDecoder().decode(message); // 把密文Base64编码字符串转回密文字节数组
            byte[] byteMessage = cipher.doFinal(encodeMessage); // 密码器解密数据

            return new String(byteMessage, StandardCharsets.UTF_8); // 将解密后的数据转换为字符串返回
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值