menu 不会旅行的兔子不是好青蛙
search self_improvement
目录

自己写的一个AES加密工具类

旅行青蛙
旅行青蛙 2023年08月15日  ·  阅读 2,320

完美的跟JS版本的AES加密库兼容

package com.wang.common.util;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.InvalidParameterSpecException;
import java.util.UUID;

/**
 * @version 1.0
 * @author: 青蛙
 * @date : 2019-01-22
 */
public class AESUtil {

    private static Boolean initialized = false;
    public static final String AES_ECB_PKCS7_PADDING = "AES/ECB/PKCS7Padding";
    public static final String AES_CBC_PKCS7_PADDING = "AES/CBC/PKCS7Padding";

    public static final String AES_ECB_PKCS5_PADDING = "AES/ECB/PKCS5Padding";
    public static final String AES_CBC_PKCS5_PADDING = "AES/CBC/PKCS5Padding";

    public static final String AES_ECB_NO_PADDING = "AES/ECB/NOPadding";
    public static final String AES_CBC_NO_PADDING = "AES/CBC/NOPadding";

    public static byte[] encrypt(String key, byte[] value, String padding) {
        try {
            Key spec = generateKey(key);
            Cipher cipher = buildCipher(padding);
            cipher.init(Cipher.ENCRYPT_MODE, spec);
            return cipher.doFinal(value);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    public static byte[] encrypt(String key, String vector, byte[] value, String padding) {
        try {
            Key spec = generateKey(key);
            AlgorithmParameters iv = generateIV(vector);
            Cipher cipher = buildCipher(padding);
            cipher.init(Cipher.ENCRYPT_MODE, spec, iv);
            return cipher.doFinal(value);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    private static Cipher buildCipher(String padding) throws NoSuchPaddingException, NoSuchAlgorithmException, NoSuchProviderException {
        Cipher cipher;
        if (padding.endsWith("PKCS7Padding")) {
            cipher = Cipher.getInstance(padding, BouncyCastleProvider.PROVIDER_NAME);
        } else {
            cipher = Cipher.getInstance(padding);
        }
        return cipher;
    }

    private static Key generateKey(byte[] key) {
        initialize();
        return new SecretKeySpec(key, "AES");
    }

    private static Key generateKey(String key) {
        return generateKey(key.getBytes(StandardCharsets.UTF_8));
    }

    private static AlgorithmParameters generateIV(byte[] vector) {
        try {
            initialize();
            AlgorithmParameters params = AlgorithmParameters.getInstance("AES");
            params.init(new IvParameterSpec(vector));
            return params;
        } catch (InvalidParameterSpecException | NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }

    private static AlgorithmParameters generateIV(String vector) {
        return generateIV(vector.getBytes(StandardCharsets.UTF_8));
    }

    public static byte[] decrypt(String key, byte[] encrypted, String padding) {
        try {
            Key spec = generateKey(key);
            Cipher cipher = buildCipher(padding);
            cipher.init(Cipher.DECRYPT_MODE, spec);
            return cipher.doFinal(encrypted);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    public static byte[] decrypt(byte[] key, byte[] vector, byte[] encrypted, String padding) {
        try {
            AlgorithmParameters iv = generateIV(vector);
            Key spec = generateKey(key);
            Cipher cipher = buildCipher(padding);
            cipher.init(Cipher.DECRYPT_MODE, spec, iv);
            return cipher.doFinal(encrypted);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    public static byte[] decrypt(String key, String vector, byte[] encrypted, String padding) {
        return decrypt(key.getBytes(StandardCharsets.UTF_8),
                       vector.getBytes(StandardCharsets.UTF_8),
                       encrypted,
                       padding);
    }

    public static String buildKey16() {
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < 4; i++) {
            String[] split = UUID.randomUUID().toString().split("-");
            builder.append(split[i], 0, 4);
        }
        return builder.toString();
    }

    public static String buildKey() {
        try {
            KeyGenerator kg = KeyGenerator.getInstance("AES");
            kg.init(128);
            //要生成多少位,只需要修改这里即可128, 192或256
            SecretKey sk = kg.generateKey();
            byte[] b = sk.getEncoded();
            return ByteUtil.bytes2Hex(b);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }

    private static void initialize() {
        if (initialized) {
            return;
        }
        Security.addProvider(new BouncyCastleProvider());
        initialized = true;
    }
}

另外为了支持“AES/ECB/PKCS7Padding”,需要替换这两个包

local_policy.jar
US_export_policy.jar

替换这两个文件的方法比较简单,根据自己的JAVA_HOME找到对应的路径,比如我的就是

java/jre/lib/security
分类:
标签: AES Java