用户注册或登录AES加密解密工具类

情景:项目在涉及到账号注册和登陆时,遇到用户密码的加密和解密过程,网上不少加密算法如MD5加密算法、DES加密算法、Base64加密算法和AES加密算法等。

在此记录目前使用比较流行的AES加密算法

AES,高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。严格地说,AES和Rijndael加密法并不完全一样(虽然在实际应用中二者可以互换),因为Rijndael加密法可以支持更大范围的区块和密钥长度:AES的区块长度固定为128 比特,密钥长度则可以是128,192或256比特;而Rijndael使用的密钥和区块长度可以是32位的整数倍,以128位为下限,256比特为上限。包括AES-ECB,AES-CBC,AES-CTR,AES-OFB,AES-CFB

经过几年时间发展,AES加密算法已成为对称密钥加密中的算法之一,也被不少大佬们封装成加密的工具类,下面介绍一下大佬Wang926454【注:大佬真名咱也不知道,嘿嘿! 那默默地使用呗】封装的AES工具类吧,废话不多说上代码:

AesCipherUtil工具类
package com.seeker.system.util;

import com.seeker.system.exception.CustomUnauthorizedException;
import com.seeker.system.util.common.Base64ConvertUtil;
import com.seeker.system.util.common.HexConvertUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.crypto.*;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.Security;

/**
 * AES加密解密工具类
 * @author Wang926454
 * @date 2018/8/31 16:39
 */
@Component
public class AesCipherUtil {

    /**
     * AES密码加密私钥(Base64加密)
     */
    private static String encryptAESKey;
    // private static final byte[] KEY = { 1, 1, 33, 82, -32, -85, -128, -65 };

    @Value("${encryptAESKey}")
    public void setEncryptAESKey(String encryptAESKey) {
        AesCipherUtil.encryptAESKey = encryptAESKey;
    }

    /**
     * logger
     */
    private static final Logger logger = LoggerFactory.getLogger(AesCipherUtil.class);

    /**
     * 加密
     * @param str
     * @return java.lang.String
     * @author Wang926454
     * @date 2018/8/31 16:56
     */
    public static String enCrypto(String str) {
        try{
            Security.addProvider(new com.sun.crypto.provider.SunJCE());
            // 实例化支持AES算法的密钥生成器(算法名称命名需按规定,否则抛出异常)
            // KeyGenerator 提供对称密钥生成器的功能,支持各种算法
            KeyGenerator keygen = KeyGenerator.getInstance("AES");
            // 将私钥encryptAESKey先Base64解密后转换为byte[]数组按128位初始化
            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
            secureRandom.setSeed(Base64ConvertUtil.decode(encryptAESKey).getBytes());
            keygen.init(128, secureRandom);
            // SecretKey 负责保存对称密钥 生成密钥
            SecretKey deskey = keygen.generateKey();
            // 生成Cipher对象,指定其支持的AES算法,Cipher负责完成加密或解密工作
            Cipher c = Cipher.getInstance("AES");
            // 根据密钥,对Cipher对象进行初始化,ENCRYPT_MODE表示加密模式
            c.init(Cipher.ENCRYPT_MODE, deskey);
            byte[] src = str.getBytes();
            // 该字节数组负责保存加密的结果
            byte[] cipherByte = c.doFinal(src);
            // 先将二进制转换成16进制,再返回Bsae64加密后的String
            return Base64ConvertUtil.encode(HexConvertUtil.parseByte2HexStr(cipherByte));
        } catch (NoSuchAlgorithmException e){
            logger.error(e.getMessage());
            throw new CustomUnauthorizedException("getInstance()方法异常:" + e.getMessage());
        } catch (UnsupportedEncodingException e){
            logger.error(e.getMessage());
            throw new CustomUnauthorizedException("Bsae64加密异常:" + e.getMessage());
        } catch (NoSuchPaddingException e){
            logger.error(e.getMessage());
            throw new CustomUnauthorizedException("getInstance()方法异常:" + e.getMessage());
        } catch (InvalidKeyException e){
            logger.error(e.getMessage());
            throw new CustomUnauthorizedException("初始化Cipher对象异常:" + e.getMessage());
        } catch (IllegalBlockSizeException e){
            logger.error(e.getMessage());
            throw new CustomUnauthorizedException("加密异常,密钥有误:" + e.getMessage());
        } catch (BadPaddingException e){
            logger.error(e.getMessage());
            throw new CustomUnauthorizedException("加密异常,密钥有误:" + e.getMessage());
        }
    }

    /**
     * 解密
     * @param str
     * @return java.lang.String
     * @author Wang926454
     * @date 2018/8/31 16:56
     */
    public static String deCrypto(String str) {
        try{
            Security.addProvider(new com.sun.crypto.provider.SunJCE());
            // 实例化支持AES算法的密钥生成器(算法名称命名需按规定,否则抛出异常)
            // KeyGenerator 提供对称密钥生成器的功能,支持各种算法
            KeyGenerator keygen = KeyGenerator.getInstance("AES");
            // 将私钥encryptAESKey先Base64解密后转换为byte[]数组按128位初始化
            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
            secureRandom.setSeed(Base64ConvertUtil.decode(encryptAESKey).getBytes());
            keygen.init(128, secureRandom);
            // SecretKey 负责保存对称密钥 生成密钥
            SecretKey deskey = keygen.generateKey();
            // 生成Cipher对象,指定其支持的AES算法,Cipher负责完成加密或解密工作
            Cipher c = Cipher.getInstance("AES");
            // 根据密钥,对Cipher对象进行初始化,DECRYPT_MODE表示解密模式
            c.init(Cipher.DECRYPT_MODE, deskey);
            // 该字节数组负责保存加密的结果,先对str进行Bsae64解密,将16进制转换为二进制
            byte[] cipherByte = c.doFinal(HexConvertUtil.parseHexStr2Byte(Base64ConvertUtil.decode(str)));
            return new String(cipherByte);
        } catch (NoSuchAlgorithmException e){
            logger.error(e.getMessage());
            throw new CustomUnauthorizedException("getInstance()方法异常:" + e.getMessage());
        } catch (UnsupportedEncodingException e){
            logger.error(e.getMessage());
            throw new CustomUnauthorizedException("Bsae64加密异常:" + e.getMessage());
        } catch (NoSuchPaddingException e){
            logger.error(e.getMessage());
            throw new CustomUnauthorizedException("getInstance()方法异常:" + e.getMessage());
        } catch (InvalidKeyException e){
            logger.error(e.getMessage());
            throw new CustomUnauthorizedException("初始化Cipher对象异常:" + e.getMessage());
        } catch (IllegalBlockSizeException e){
            logger.error(e.getMessage());
            throw new CustomUnauthorizedException("解密异常,密钥有误:" + e.getMessage());
        } catch (BadPaddingException e){
            logger.error(e.getMessage());
            throw new CustomUnauthorizedException("解密异常,密钥有误:" + e.getMessage());
        }
    }
}

在这个类之中需要其他几个公共类,不然会报错,下面是公共类,需要使用copy项目中创建一下,然后改一下上面类路径即可使用。

【1】CustomUnauthorizedException异常处理类

package com.seeker.system.exception;

/**
 * 自定义401无权限异常(UnauthorizedException)
 * @author Wang926454
 * @date 2018/8/30 13:59
 */
public class CustomUnauthorizedException extends RuntimeException {

    public CustomUnauthorizedException(String msg){
        super(msg);
    }

    public CustomUnauthorizedException() {
        super();
    }
}

【2】Base64ConvertUtil类

package com.seeker.system.util.common;

import java.io.UnsupportedEncodingException;
import java.util.Base64;

/**
 * Base64工具
 * @author Wang926454
 * @date 2018/8/21 15:14
 */
public class Base64ConvertUtil {

    /**
     * 加密JDK1.8
     * @param str
     * @return java.lang.String
     * @author Wang926454
     * @date 2018/8/21 15:28
     */
    public static String encode(String str) throws UnsupportedEncodingException {
        byte[] encodeBytes = Base64.getEncoder().encode(str.getBytes("utf-8"));
        return new String(encodeBytes);
    }

    /**
     * 解密JDK1.8
     * @param str
     * @return java.lang.String
     * @author Wang926454
     * @date 2018/8/21 15:28
     */
    public static String decode(String str) throws UnsupportedEncodingException {
        byte[] decodeBytes = Base64.getDecoder().decode(str.getBytes("utf-8"));
        return new String(decodeBytes);
    }

    public static void main(String[] args) throws UnsupportedEncodingException {
        System.out.println(decode("U0JBUElKV1RkV2FuZzkyNjQ1NA=="));
    }

}
【3】HexConvertUtil 进制转换类
package com.seeker.system.util.common;

/**
 * 进制转换工具
 * @author Wang926454
 * @date 2018/8/31 17:23
 */
public class HexConvertUtil {

    /**
     * 1
     */
    private static final Integer INTEGER_1 = 1;

    /**
     * 2
     */
    private static final Integer INTEGER_2 = 2;

    /**
     * 将二进制转换成16进制
     * @param buff
     * @return java.lang.String
     * @author Wang926454
     * @date 2018/8/31 17:20
     */
    public static String parseByte2HexStr(byte[] buff) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0, len = buff.length; i < len; i++) {
            String hex = Integer.toHexString(buff[i] & 0xFF);
            if (hex.length() == INTEGER_1) {
                hex = '0' + hex;
            }
            sb.append(hex.toUpperCase());
        }
        return sb.toString();
    }

    /**
     * 将16进制转换为二进制
     * @param hexStr
     * @return byte[]
     * @author Wang926454
     * @date 2018/8/31 17:21
     */
    public static byte[] parseHexStr2Byte(String hexStr) {
        if (hexStr.length() < INTEGER_1){
            return null;
        }
        byte[] result = new byte[hexStr.length() / INTEGER_2];
        for (int i = 0, len = hexStr.length() / INTEGER_2;i < len; 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;
    }
}

【4】配置文件config.properties,【注:如果不配置AES密码加密密钥会报错的】

# AES密码加密私钥(Base64加密)
encryptAESKey=V2FuZzkyNjQ1NGRTQkFQSUpXVA==

这边账号密码的加密方式是【登录名+密码】,当然也可不用加上用户名,根据自己需要来用哦,例如项目中调用:


//注册时对密码AES加密
String key = AesCipherUtil.enCrypto(sysUser.getLoginName() + sysUser.getPassword());


// 密码进行AES解密
String key = AesCipherUtil.deCrypto(sysUser.getPassword());

OK 这次就到这里啦

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是 Java 中使用 AES 加密解密工具类,其中包括了 AES/CBC/PKCS5Padding 算法的加密解密方法: ```java import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.nio.charset.StandardCharsets; import java.util.Base64; public class AESUtil { private static final String ALGORITHM_AES = "AES"; private static final String CIPHER_AES_CBC_PKCS5PADDING = "AES/CBC/PKCS5Padding"; private static final String IV = "0123456789abcdef"; // 16 位 /** * AES 加密 * * @param data 需要加密的数据 * @param key 密钥字符串(16、24 或 32 位) * @return 加密后的字符串 */ public static String encryptByAES(String data, String key) { try { byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8); SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, ALGORITHM_AES); Cipher cipher = Cipher.getInstance(CIPHER_AES_CBC_PKCS5PADDING); IvParameterSpec ivParameterSpec = new IvParameterSpec(IV.getBytes(StandardCharsets.UTF_8)); cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec); byte[] encryptedBytes = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8)); return Base64.getEncoder().encodeToString(encryptedBytes); } catch (Exception e) { e.printStackTrace(); } return null; } /** * AES 解密 * * @param data 需要解密的数据 * @param key 密钥字符串(16、24 或 32 位) * @return 解密后的字符串 */ public static String decryptByAES(String data, String key) { try { byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8); SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, ALGORITHM_AES); Cipher cipher = Cipher.getInstance(CIPHER_AES_CBC_PKCS5PADDING); IvParameterSpec ivParameterSpec = new IvParameterSpec(IV.getBytes(StandardCharsets.UTF_8)); cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec); byte[] encryptedBytes = Base64.getDecoder().decode(data); byte[] decryptedBytes = cipher.doFinal(encryptedBytes); return new String(decryptedBytes, StandardCharsets.UTF_8); } catch (Exception e) { e.printStackTrace(); } return null; } } ``` 使用示例: ```java public static void main(String[] args) { String data = "Hello, world!"; String key = "1234567890123456"; String encryptedData = AESUtil.encryptByAES(data, key); System.out.println("加密后的数据:" + encryptedData); String decryptedData = AESUtil.decryptByAES(encryptedData, key); System.out.println("解密后的数据:" + decryptedData); } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值