All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.kaizen4j.algorithm.encrypt.Aes Maven / Gradle / Ivy

package com.github.kaizen4j.algorithm.encrypt;

import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;

/**
 * AES 加密类
 *
 * @author liuguowen
 */
public final class Aes {

    private static final String AES_DECRYPTION = "AES";

    private static final String CIPHER_PADDING = "AES/GCM/NoPadding";

    private static final String SHA1PRNG = "SHA1PRNG";

    private static final int KEY_SIZE_128 = 128;

    private static final int KEY_SIZE_192 = 192;

    private static final int KEY_SIZE_256 = 256;

    private Aes() {
    }

    /**
     * 生成密钥
     *
     * @param keySize AES 密钥长度
     * @return 二进制密钥字节数组
     */
    private static byte[] getKey(int keySize) {
        return getKey(keySize, StringUtils.EMPTY);
    }

    public static byte[] getKey128() {
        return getKey(KEY_SIZE_128);
    }

    public static byte[] getKey128(String keyStr) {
        return getKey(KEY_SIZE_128, keyStr);
    }

    public static byte[] getKey192() {
        return getKey(KEY_SIZE_192);
    }

    public static byte[] getKey192(String keyStr) {
        return getKey(KEY_SIZE_192, keyStr);
    }

    public static byte[] getKey256() {
        return getKey(KEY_SIZE_256);
    }

    public static byte[] getKey256(String keyStr) {
        return getKey(KEY_SIZE_256, keyStr);
    }

    /**
     * 生成自定义密钥
     *
     * @param keySize AES 密钥长度
     * @param keyString 自定义密钥字符串
     * @return 二进制密钥字节数组
     */
    private static byte[] getKey(int keySize, String keyString) {
        try {
            KeyGenerator keyGenerator = KeyGenerator.getInstance(AES_DECRYPTION);
            // 解决 Linux 下生成 key 不一样的问题
            SecureRandom secureRandom = SecureRandom.getInstance(SHA1PRNG);
            secureRandom.setSeed(keyString.getBytes(StandardCharsets.UTF_8));
            keyGenerator.init(keySize, secureRandom);
            SecretKey secretKey = keyGenerator.generateKey();
            // 获取二进制密钥编码形式
            return secretKey.getEncoded();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 转换密钥
     *
     * @param keyBytes 二进制密钥
     * @return 密钥 SecretKey 对象
     */
    private static SecretKeySpec toSecretKey(byte[] keyBytes) {
        return new SecretKeySpec(keyBytes, AES_DECRYPTION);
    }

    /**
     * 加密数据
     *
     * @param data 待加密数据字符串
     * @param keyBytes 密钥字节数组
     * @return 加密后的数据字符串
     */
    public static String encrypt(String data, byte[] keyBytes) {
        try {
            Cipher cipher = Cipher.getInstance(CIPHER_PADDING);
            SecretKeySpec keySpec = toSecretKey(keyBytes);

            GCMParameterSpec iv = getGCMParameterSpec(keySpec);
            cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);

            byte[] dataBytes = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
            return Base64.encodeBase64String(dataBytes);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private static GCMParameterSpec getGCMParameterSpec(SecretKeySpec skeySpec) {
        return new GCMParameterSpec(128, skeySpec.getEncoded(), 0, 16);
    }

    /**
     * 解密数据
     *
     * @param data 待解密数据字符串
     * @param keyBytes 密钥字节数组
     * @return 解密后的数据字符串
     */
    public static String decrypt(String data, byte[] keyBytes) {
        try {
            Cipher cipher = Cipher.getInstance(CIPHER_PADDING);
            SecretKeySpec keySpec = toSecretKey(keyBytes);

            GCMParameterSpec iv = getGCMParameterSpec(keySpec);
            cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);

            byte[] dataBytes = Base64.decodeBase64(data);
            return new String(cipher.doFinal(dataBytes));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy