Java实现AES加解密

一、需求

  • 算法支持16位密钥和32位密钥加密。
  • 支持CBC、EBC模式
  • base64、HEX返回值

二、实现32位密钥加密

jdk默认只支持16位密钥,如果直接使用32位密钥,报错:

因此,让算法支持32位密钥加密。需要更新默认jar包:

 jar包下载地址(jdk8):http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html

或者:

支持32位密钥的AES加解密资源-CSDN文库icon-default.png?t=N4P3https://download.csdn.net/download/qq_41605068/87831826?spm=1001.2014.3001.5503

三、代码

package com.example.zichu.util;

import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.Base64Utils;

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

/**
 * AES加密工具类
 *
 * @author ACGkaka
 * @since 2021-06-18 19:11:03
 */

public class AESUtil {

    /**
     * 日志相关
     */
//    private static final Logger LOGGER = LoggerFactory.getLogger(AESUtil.class);
    /**
     * 编码
     */
    private static final String ENCODING = "UTF-8";
    /**
     * 算法定义
     */
    private static final String AES_ALGORITHM = "AES";
    /**
     * 指定填充方式
     */
    private static final String CIPHER_PADDING = "AES/ECB/PKCS5Padding";
    private static final String CIPHER_CBC_PADDING = "AES/CBC/PKCS5Padding";
    /**
     * 偏移量(CBC中使用,增强加密算法强度)
     */

    /**
     * AES加密
     *
     * @param content 待加密内容
     * @param aesKey  密码
     * @return
     */
    public static String encrypt(String content, String aesKey) {
        if (StringUtils.isBlank(content)) {
            System.out.println("AES encrypt: the content is null!");
            return null;
        }
        //判断秘钥是否为16位
        if (StringUtils.isNotBlank(aesKey) && aesKey.length() == 16) {
            try {
                //对密码进行编码
                byte[] bytes = aesKey.getBytes(ENCODING);
                //设置加密算法,生成秘钥
                SecretKeySpec skeySpec = new SecretKeySpec(bytes, AES_ALGORITHM);
                // "算法/模式/补码方式"
                Cipher cipher = Cipher.getInstance(CIPHER_PADDING);
                //选择加密
                cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
                //根据待加密内容生成字节数组
                byte[] encrypted = cipher.doFinal(content.getBytes(ENCODING));
                //返回base64字符串
                return Base64Utils.encodeToString(encrypted);
            } catch (Exception e) {
                System.out.println("AES encrypt exception:" + e.getMessage());
                throw new RuntimeException(e);
            }

        } else {
            System.out.println("AES encrypt: the aesKey is null or error!");
            return null;
        }
    }

    /**
     * 解密
     *
     * @param content 待解密内容
     * @param aesKey  密码
     * @return
     */
    public static String decrypt(String content, String aesKey) {
        if (StringUtils.isBlank(content)) {
            System.out.println("AES decrypt: the content is null!");
            return null;
        }
        //判断秘钥是否为16位
        if (StringUtils.isNotBlank(aesKey) && aesKey.length() == 16) {
            try {
                //对密码进行编码
                byte[] bytes = aesKey.getBytes(ENCODING);
                //设置解密算法,生成秘钥
                SecretKeySpec skeySpec = new SecretKeySpec(bytes, AES_ALGORITHM);
                // "算法/模式/补码方式"
                Cipher cipher = Cipher.getInstance(CIPHER_PADDING);
                //选择解密
                cipher.init(Cipher.DECRYPT_MODE, skeySpec);

                //先进行Base64解码
                byte[] decodeBase64 = Base64Utils.decodeFromString(content);

                //根据待解密内容进行解密
                byte[] decrypted = cipher.doFinal(decodeBase64);
                //将字节数组转成字符串
                return new String(decrypted, ENCODING);
            } catch (Exception e) {
                System.out.println("AES decrypt exception:" + e.getMessage());
                throw new RuntimeException(e);
            }

        } else {
            System.out.println("AES decrypt: the aesKey is null or error!");
            return null;
        }
    }

    /**
     * AES_CBC加密
     *
     * @param content 待加密内容
     * @param aesKey  密码-base64
     * @return
     */
    public static String encryptCBC(String content, String aesKey, String IV_SEED) {
        if (StringUtils.isBlank(content)) {
            System.out.println("AES_CBC encrypt: the content is null!");
            return null;
        }
        //判断秘钥是否为32位
        if (StringUtils.isNotBlank(aesKey) && aesKey.length() == 32) {
            try {
                //对密码进行编码
                byte[] bytes = aesKey.getBytes(ENCODING);
                //设置加密算法,生成秘钥
                SecretKeySpec skeySpec = new SecretKeySpec(bytes, AES_ALGORITHM);
                // "算法/模式/补码方式"
                Cipher cipher = Cipher.getInstance(CIPHER_CBC_PADDING);
                //偏移
                IvParameterSpec iv = new IvParameterSpec(IV_SEED.getBytes(ENCODING));
                //选择加密
                cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
                //根据待加密内容生成字节数组
                byte[] encrypted = cipher.doFinal(content.getBytes(ENCODING));
                //返回base64字符串
                return Base64Utils.encodeToString(encrypted);
            } catch (Exception e) {
                System.out.println("AES_CBC encrypt exception:" + e.getMessage());
                throw new RuntimeException(e);
            }

        } else {
            System.out.println("AES_CBC encrypt: the aesKey is null or error!");
            return null;
        }
    }

    /**
     * AES_CBC解密
     *
     * @param content 待解密内容
     * @param aesKey  密码
     * @return
     */
    public static String decryptCBC(String content, String aesKey, String IV_SEED) {
        if (StringUtils.isBlank(content)) {
            System.out.println("AES_CBC decrypt: the content is null!");
            return null;
        }
        //判断秘钥是否为32位
        if (StringUtils.isNotBlank(aesKey) && aesKey.length() == 32) {
            try {
                //对密码进行编码
                byte[] bytes = aesKey.getBytes(ENCODING);
                //设置解密算法,生成秘钥
                SecretKeySpec skeySpec = new SecretKeySpec(bytes, AES_ALGORITHM);
                //偏移
                IvParameterSpec iv = new IvParameterSpec(IV_SEED.getBytes(ENCODING));
                // "算法/模式/补码方式"
                Cipher cipher = Cipher.getInstance(CIPHER_CBC_PADDING);
                //选择解密
                cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);

                //先进行Base64解码
                byte[] decodeBase64 = Base64Utils.decodeFromString(content);

                //根据待解密内容进行解密
                byte[] decrypted = cipher.doFinal(decodeBase64);
                //将字节数组转成字符串
                return new String(decrypted, ENCODING);
            } catch (Exception e) {
                System.out.println("AES_CBC decrypt exception:" + e.getMessage());
                throw new RuntimeException(e);
            }

        } else {
            System.out.println("AES_CBC decrypt: the aesKey is null or error!");
            return null;
        }
    }


    /**
     * AES_CBC加密
     *
     * @param content 待加密内容
     * @return
     */
    public static String encryptCBC_HEX(String content) {
        if (StringUtils.isBlank(content)) {
            System.out.println("AES_CBC_HEX encrypt: the content is null!");
            return null;
        }
        //判断秘钥是否为16位
        if (StringUtils.isNotBlank(aesKey) && aesKey.length() == 16) {
            try {
                //对密码进行编码
                byte[] bytes = aesKey.getBytes(ENCODING);
                //设置加密算法,生成秘钥
                SecretKeySpec skeySpec = new SecretKeySpec(bytes, AES_ALGORITHM);
                // "算法/模式/补码方式"
                Cipher cipher = Cipher.getInstance(CIPHER_CBC_PADDING);
                //偏移
                IvParameterSpec iv = new IvParameterSpec(IV_SEED.getBytes(ENCODING));
                //选择加密
                cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
                //根据待加密内容生成字节数组
                byte[] encrypted = cipher.doFinal(content.getBytes(ENCODING));
                String s = Hex.encodeHexString(encrypted);
                //返回
                return s;
            } catch (Exception e) {
                System.out.println("AES_CBC_HEX encrypt exception:" + e.getMessage());
                throw new RuntimeException(e);
            }

        } else {
            System.out.println("AES_CBC_HEX encrypt: the aesKey is null or error!");
            return null;
        }
    }

   
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值