AESUtil

看了几个别人写的,不好用,还是自动总结一下,不BB直接上代码,

缺依赖自己根据 import

import com.alibaba.fastjson.JSON;
import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.validation.constraints.NotNull;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.Security;
import java.text.DecimalFormat;
import java.util.*;

public class AESUtil {

    private static final String AES = "AES";
    private static final String DEFAULT_IV = "1234567890123456";

    static {
        Security.addProvider(new BouncyCastleProvider());
    }

    public static void main(String[] args) throws Exception {

        DecimalFormat nf = new DecimalFormat("16880000000");

        List<Map<String, Object>> data = new ArrayList<>();
        for (int i = 1; i <= 500; i++) {
            Map<String, Object> curr = new LinkedHashMap<>();
            curr.put("姓名", "曾特喵穷" + i);
            curr.put("手机号", nf.format(i));
            data.add(curr);
        }
        Map<String, Object> map = new HashMap<>();
        map.put("data", data);
        String wait = JSON.toJSONString(map);
        System.out.println("wait => " + wait);

        // 长度可以是 16/24/32
        String key = "12345678123456781234567812345678";

        for (AlgorithmEnum algorithm : AlgorithmEnum.values()) {
            System.out.println(algorithm.name);
            //
            String encrypt = encrypt(wait, key, DEFAULT_IV, algorithm);
            System.out.println("\t=> " + encrypt);
            //
            String decrypt = decrypt(encrypt, key, DEFAULT_IV, algorithm);
            System.out.println("\t=> " + decrypt);
        }

    }

    /**
     * 先AES加密,再将进行Base64转码,输出密钥字符串
     *
     * @param wait      待加密字符串
     * @param key       密码,16、24、32位
     * @param iv        向量,必须16位
     * @param algorithm 算法
     * @return
     * @throws Exception
     */
    public static String encrypt(@NotNull String wait, @NotNull String key, String iv, @NotNull AESUtil.AlgorithmEnum algorithm) throws Exception {
        return encrypt(wait, key, iv, algorithm, StandardCharsets.UTF_8);
    }

    /**
     * 先AES加密,再将进行Base64转码,输出密钥字符串
     *
     * @param wait      待加密字符串
     * @param key       密码,16、24、32位
     * @param iv        向量,必须16位
     * @param algorithm 算法
     * @param charset   字符集
     * @return
     * @throws Exception
     */
    public static String encrypt(@NotNull String wait, @NotNull String key, String iv, @NotNull AESUtil.AlgorithmEnum algorithm, @NotNull Charset charset) throws Exception {
        // 按照 mode 生成实例
        Cipher cipher = cipherInstance(Cipher.ENCRYPT_MODE, key, iv, algorithm, charset);
        // 字节码加密
        byte[] b = cipher.doFinal(wait.getBytes(charset));
        // 字节码转字符串
        return new Base64().encodeToString(b);
    }

    /**
     * 先将密钥base64解码,再进行AES解密,输出解密字符串
     *
     * @param wait      待解密密钥
     * @param key       密码,16、24、32位
     * @param iv        向量,必须16位
     * @param algorithm 算法
     * @return
     * @throws Exception
     */
    public static String decrypt(@NotNull String wait, @NotNull String key, String iv, @NotNull AESUtil.AlgorithmEnum algorithm) throws Exception {
        return decrypt(wait, key, iv, algorithm, StandardCharsets.UTF_8);
    }

    /**
     * 先将密钥base64解码,再进行AES解密,输出字符串
     *
     * @param wait      待解密密钥
     * @param key       密码,16、24、32位
     * @param iv        向量,必须16位
     * @param algorithm 算法
     * @param charset   字符集
     * @return
     * @throws Exception
     */
    public static String decrypt(@NotNull String wait, @NotNull String key, String iv, @NotNull AESUtil.AlgorithmEnum algorithm, @NotNull Charset charset) throws Exception {
        // 按照 mode 生成实例
        Cipher cipher = cipherInstance(Cipher.DECRYPT_MODE, key, iv, algorithm, charset);
        // Base64 解码后解密
        byte[] b = cipher.doFinal(Base64.decodeBase64(wait));
        // 字节码转字符串
        return new String(b, charset);
    }

    /**
     * 按照配置生成 Cipher 实例
     *
     * @param mode      加密或解密
     * @param key       密码,16、24、32位
     * @param iv        向量,必须16位
     * @param algorithm 算法
     * @param charset   字符集
     * @return
     * @throws Exception
     */
    public static Cipher cipherInstance(@NotNull int mode, @NotNull String key, String iv, @NotNull AESUtil.AlgorithmEnum algorithm, @NotNull Charset charset) throws Exception {
        Cipher cipher = Cipher.getInstance(algorithm.name);
        SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(charset), AES);
        if (algorithm.ivFlag && null != iv) {
            IvParameterSpec ivSpec = new IvParameterSpec(iv.getBytes(charset));
            cipher.init(mode, keySpec, ivSpec);
        } else {
            cipher.init(mode, keySpec);
        }
        return cipher;
    }

    public enum AlgorithmEnum {
        /*
            算法/模式/填充             16字节加密后数据长度    不满16字节加密后长度
            AES/CBC/NoPadding             16                    不支持
            AES/CBC/PKCS5Padding          32                    16
            AES/CBC/ISO10126Padding       32                    16
            AES/CFB/NoPadding             16                    原始数据长度
            AES/CFB/PKCS5Padding          32                    16
            AES/CFB/ISO10126Padding       32                    16
            AES/ECB/NoPadding             16                    不支持
            AES/ECB/PKCS5Padding          32                    16
            AES/ECB/ISO10126Padding       32                    16
            AES/OFB/NoPadding             16                    原始数据长度
            AES/OFB/PKCS5Padding          32                    16
            AES/OFB/ISO10126Padding       32                    16
            AES/PCBC/NoPadding            16                    不支持
            AES/PCBC/PKCS5Padding         32                    16
            AES/PCBC/ISO10126Padding      32                    16
         */

        // 算法/模式/补码方式
        CBC_PKCS5("AES/CBC/PKCS5Padding", true),
        CBC_PKCS7("AES/CBC/PKCS7Padding", true),
        CBC_ISO10126("AES/CBC/ISO10126Padding", true),

        CFB_NO("AES/CFB/NoPadding", true),
        CFB_PKCS5("AES/CFB/PKCS5Padding", true),
        CFB_PKCS7("AES/CFB/PKCS7Padding", true),
        CFB_ISO10126("AES/CFB/ISO10126Padding", true),

        ECB_PKCS5("AES/ECB/PKCS5Padding", false),
        ECB_PKCS7("AES/ECB/PKCS7Padding", false),
        ECB_ISO10126("AES/ECB/ISO10126Padding", false),

        OFB_NO("AES/OFB/NoPadding", true),
        OFB_PKCS5("AES/OFB/PKCS5Padding", true),
        OFB_PKCS7("AES/OFB/PKCS7Padding", true),
        OFB_ISO10126("AES/OFB/ISO10126Padding", true),

        PCBC_PKCS5("AES/PCBC/PKCS5Padding", true),
        PCBC_ISO10126("AES/PCBC/ISO10126Padding", true);

        /**
         * 算法
         */
        private String name;
        /**
         * IV标识
         */
        private boolean ivFlag;

        AlgorithmEnum(String name, boolean ivFlag) {
            this.name = name;
            this.ivFlag = ivFlag;
        }

        public String getName() {
            return name;
        }

        public boolean getIvFlag() {
            return ivFlag;
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值