AES加解密工具类

import org.apache.commons.codec.binary.Base64;

import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

/**
 * @author lanjingjing
 * @description AES
 * @date 2020/5/31
 *
 *
 * 此加解密仅涉及:AES/CBC/PKCS5Padding
 *              AES/ECB/ZeroPadding
 *
 *
 * 注:CBC 模式 需要设置 key(秘钥) ,iv(初始化向量)
 *    ECB 模式 仅需要设置key(秘钥),无需设置 iv
 *
 *  特殊说明:补码方式-ZeroPadding:java中无此补码方式,原理是将分组密码不足分组长度的整数倍时以0填充
 *
 *
 *
 */
public class AESUtil {

    /**
     * 初始化向量
     */
    private static String ivs = "Ym888pPr888pc888";
    /**
     * 秘钥
     */
    private static String key = "3Cdp488899rC888T";

    /**
     * 随机生成AES128位密钥字符串
     * 注:秘钥经过Base64.encode,使用该秘钥进行加解密时需要
     */
    public  static String  genKeyString(){
        String key = null;
        try {
            KeyGenerator kg = KeyGenerator.getInstance("AES");
            kg.init(128,new SecureRandom());//要生成多少位,只需要修改这里即可128, 192或256
            SecretKey sk = kg.generateKey();
            byte[] b = sk.getEncoded();
            key = Base64.encodeBase64String(b);
            key = key.replaceAll("[\\s*\t\n\r]", "");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            System.out.println("没有此算法。");//TODO
        }
        return key;
    }

    /**
     * 生成128位秘钥数组
     * @return
     */
    public  static byte[]  genKeyBytes(){
        byte[] keyBytes= new byte[128];
        try {
            KeyGenerator kg = KeyGenerator.getInstance("AES");
            kg.init(128,new SecureRandom());//要生成多少位,只需要修改这里即可128, 192或256
            SecretKey sk = kg.generateKey();
            keyBytes = sk.getEncoded();


        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            System.out.println("没有此算法。");//TODO
        }
        return keyBytes;
    }



    /**
     *  使用对称密钥进行加密
     * @param keyb  genKeyBytes()中生成的key字节数组
     * @param oriContent    原文(UTF-8编码)
     * @return
     * @throws Exception
     * 注:默认UTF-8编码,加密之后用BASE64进行转码
     */
    public static String  encrpt(byte[] keyb,String oriContent) throws Exception{

        SecretKeySpec sKeySpec = new SecretKeySpec(keyb, "AES");
        IvParameterSpec iv = new IvParameterSpec(ivs.getBytes());//向量iv,使用CBC模式需要指定iv

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, sKeySpec,iv);
        byte[] encrptBytes = cipher.doFinal(oriContent.getBytes("UTF-8"));
        String encreptContent = Base64.encodeBase64String(encrptBytes);
        encreptContent = encreptContent.replaceAll("[\\s*\t\n\r]", "");
        return encreptContent;
    }

    /**
     *  使用对称密钥进行加密
     * @param key  genKeyString()中生成的key字符
     * @param oriContent    原文(UTF-8编码)
     * @return
     * @throws Exception
     * 注:默认UTF-8编码,加密之后用BASE64进行转码
     */
    public static String  encrpt(String key,String oriContent) throws Exception{

        byte[] keyb = Base64.decodeBase64(key);// 秘钥进行Base64 解码

        SecretKeySpec sKeySpec = new SecretKeySpec(keyb, "AES");
        IvParameterSpec iv = new IvParameterSpec(ivs.getBytes());//向量iv,使用CBC模式需要指定iv

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, sKeySpec,iv);
        byte[] encrptBytes = cipher.doFinal(oriContent.getBytes("UTF-8"));
        String encreptContent = Base64.encodeBase64String(encrptBytes);
        encreptContent = encreptContent.replaceAll("[\\s*\t\n\r]", "");
        return encreptContent;
    }

    /**
     * 使用对称密钥进行解密
     * @param keyb genKeyBytes()中生成的key字节数组
     * @param encrptContent 经过Base64转码之后的密文
     * @throws Exception
     */
    public static void decrpt(byte[] keyb,String encrptContent) throws Exception{

        byte[] encrptBytes = Base64.decodeBase64(encrptContent);// 先将密文解码
        SecretKeySpec sKeySpec = new SecretKeySpec(keyb, "AES");
        IvParameterSpec iv = new IvParameterSpec(ivs.getBytes());//使用CBC模式需要添加向量iv,非CBC可以不用增加向量IV

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, sKeySpec,iv);

        byte[] decrptContent = cipher.doFinal(encrptBytes);
        System.out.println("Decrpt:"+new String(decrptContent));
    }


    /**
     * 使用对称密钥进行解密
     * @param key genKeyString()中生成的key字节数组
     * @param encrptContent 经过Base64转码之后的密文
     * @throws Exception
     */
    public static void decrpt(String key,String encrptContent) throws Exception{

        byte[] encrptBytes = Base64.decodeBase64(encrptContent);// 先将密文解码
        byte[] keyb = Base64.decodeBase64(key);// key使用Base64 进行转码


        SecretKeySpec sKeySpec = new SecretKeySpec(keyb, "AES");
        IvParameterSpec iv = new IvParameterSpec(ivs.getBytes());//使用CBC模式需要添加向量iv,非CBC可以不用增加向量IV

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, sKeySpec,iv);

        byte[] decrptContent = cipher.doFinal(encrptBytes);
        System.out.println("Decrpt:"+new String(decrptContent));
    }

    /**
     * 加密
     * @since  算法/模式/补码方式:AES/CBC/ZeroPadding
     * @param data
     * @return 加密的数据
     * @doc  ZeroPadding:不足16位的整数倍补0
     */
    public static String encrypt_CBC_ZeroPadding(String data) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
        String ivString = ivs;
        //偏移量
        byte[] iv = ivString.getBytes();
        Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
        int blockSize = cipher.getBlockSize();
        byte[] dataBytes = data.getBytes();
        int length = dataBytes.length;
        //计算需填充长度
        if (length % blockSize != 0) {
            length = length + (blockSize - (length % blockSize));
        }
        byte[] plaintext = new byte[length];
        //填充
        System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length);
        SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "AES");
        //设置偏移量参数
        IvParameterSpec ivSpec = new IvParameterSpec(iv);
        cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
        byte[] encryped = cipher.doFinal(plaintext);
        return Base64.encodeBase64String(encryped).replaceAll("[\\s*\t\n\r]", "");
    }


    /**
     * 解密
     * @since 算法/模式/补码方式:AES/CBC/ZeroPadding
     * @param data
     * @return
     */
    public static String dencrypt_CBC_ZeroPadding(String data) throws NoSuchPaddingException, NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException, InvalidAlgorithmParameterException, InvalidKeyException {
        byte[] iv = ivs.getBytes();

        byte[] encryp = Base64.decodeBase64(data);

        Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
        SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "AES");
        IvParameterSpec ivSpec = new IvParameterSpec(iv);
        cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
        byte[] original = cipher.doFinal(encryp);

        return new String(original).trim();// 解密之后去除加密时补的0(空字符串)
    }
    /**
     * @since  使用对称密钥进行加密  算法/模式/不骂方式:AES/ECB/PKCS5Padding
     * @param key  genKeyString()中生成的key字符
     * @param oriContent    原文(UTF-8编码)
     * @return
     * @throws Exception
     * 注:默认UTF-8编码,加密之后用BASE64进行转码
     */
    public static String  encrpt_ECB_PKCS5Padding(String key,String oriContent) throws Exception{

        byte[] keyb = Base64.decodeBase64(key);// 秘钥进行Base64 解码
        SecretKeySpec sKeySpec = new SecretKeySpec(keyb, "AES");
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, sKeySpec);// ECB 模式不需要设置iv
        byte[] encrptBytes = cipher.doFinal(oriContent.getBytes("UTF-8"));
        String encreptContent = Base64.encodeBase64String(encrptBytes);
        encreptContent = encreptContent.replaceAll("[\\s*\t\n\r]", "");
        return encreptContent;
    }
    /**
     * 使用对称密钥进行解密
     * @param key genKeyString()中生成的key字节数组
     * @param encrptContent 经过Base64转码之后的密文
     * @throws Exception
     */
    public static String decrpt_ECB_PKCS5Padding(String key,String encrptContent) throws Exception{

        byte[] encrptBytes = Base64.decodeBase64(encrptContent);// 先将密文解码
        byte[] keyb = Base64.decodeBase64(key);// key使用Base64 进行转码
        SecretKeySpec sKeySpec = new SecretKeySpec(keyb, "AES");
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, sKeySpec);// ECB模式不使用iv

        byte[] decrptContent = cipher.doFinal(encrptBytes);
        return new String(decrptContent);
    }
    public static void main(String[] args) throws Exception {

        String oriContent = "hello world! 你好世界";
        /* 方法1:使用生成key字节数组进行加解密*/
        byte[] keyBytes = genKeyBytes();// 生成key字节数组
        String encrptContent = encrpt(keyBytes, oriContent);
        System.out.println("encrpt:"+encrptContent);
        decrpt(keyBytes,encrptContent);

        /* 方法2:使用生成的key字符串进行加解密*/
        String key = genKeyString();
        String encrptContent2 = encrpt(key, oriContent);
        System.out.println("encrpt2:"+encrptContent2);
        decrpt(key,encrptContent2);



        // AES/CBC/ZeroPadding 进行加解密
        String data = "hello world ~,你好,中国发骄傲了房间里撒娇砥砺奋进爱睡懒觉按实际发的垃圾四六级卡视角东方丽景爱上了就发啦老实交代冷风机案例所肩负的两三放两三点冷风机三街坊邻居了就两块三分段了就撒里的解放路卡机是两地分居";
        String encrypt = encrypt_CBC_ZeroPadding(data);
        String desencrypt =dencrypt_CBC_ZeroPadding (encrypt);
        System.out.println("AES/CBC/ZeroPadding-加密后:"+encrypt);
        System.out.println("AES/CBC/ZeroPadding-解密后:"+desencrypt);

//        // AES/ECB/PKCS5Padding 进行加解密 这里使用随机生成的key
        String ikey = AESUtil.genKeyString();
        String encrptContent3 = encrpt_ECB_PKCS5Padding(ikey, data);
        System.out.println("AES/ECB/PKCS5Padding -加密的数据:"+encrptContent3);
        String decrptContent = decrpt_ECB_PKCS5Padding(ikey, encrptContent3);
        System.out.println("AES/ECB/PKCS5Padding -解密的数据:"+decrptContent);



    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下为Java的AES加密解密工具类: ```java import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.util.Base64; public class AESUtil { private static final String ALGORITHM = "AES/CBC/PKCS5Padding"; private static final String CHARSET = "UTF-8"; /** * 加密 * @param data 待加密的字符串 * @param key 密钥 * @param iv 向量 * @return 加密后的字符串 */ public static String encrypt(String data, String key, String iv) { try { Cipher cipher = Cipher.getInstance(ALGORITHM); SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), "AES"); IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes()); cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec); byte[] encrypted = cipher.doFinal(data.getBytes(CHARSET)); return Base64.getEncoder().encodeToString(encrypted); } catch (Exception e) { e.printStackTrace(); } return null; } /** * 解密 * @param data 待解密的字符串 * @param key 密钥 * @param iv 向量 * @return 解密后的字符串 */ public static String decrypt(String data, String key, String iv) { try { Cipher cipher = Cipher.getInstance(ALGORITHM); SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), "AES"); IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes()); cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec); byte[] decrypted = cipher.doFinal(Base64.getDecoder().decode(data)); return new String(decrypted, CHARSET); } catch (Exception e) { e.printStackTrace(); } return null; } } ``` 使用示例: ```java public class Main { public static void main(String[] args) { String data = "Hello, world!"; String key = "1234567890123456"; String iv = "1234567890123456"; String encrypted = AESUtil.encrypt(data, key, iv); String decrypted = AESUtil.decrypt(encrypted, key, iv); System.out.println("明文:" + data); System.out.println("加密后:" + encrypted); System.out.println("解密后:" + decrypted); } } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值