杰瑞科技汇

Java AES256加密如何实现?

Java AES-256 加密实现

AES-256 是一种对称加密算法,使用 256 位密钥,以下是 Java 中实现 AES-256 加密和解密的完整示例。

Java AES256加密如何实现?-图1
(图片来源网络,侵删)

基本实现

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.Base64;
public class AES256Util {
    // 算法名称
    private static final String ALGORITHM = "AES";
    // 加密模式/填充方式
    private static final String TRANSFORMATION = "AES/CBC/PKCS5Padding";
    // IV长度 (AES块大小是128位)
    private static final int IV_LENGTH = 16;
    // 密钥长度 (AES-256需要32字节)
    private static final int KEY_LENGTH = 256;
    /**
     * 生成AES-256密钥
     */
    public static SecretKey generateKey() throws Exception {
        KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM);
        keyGenerator.init(KEY_LENGTH);
        return keyGenerator.generateKey();
    }
    /**
     * 从字节数组创建密钥
     */
    public static SecretKey getKeyFromBytes(byte[] keyBytes) {
        return new SecretKeySpec(keyBytes, ALGORITHM);
    }
    /**
     * 从Base64字符串创建密钥
     */
    public static SecretKey getKeyFromString(String keyString) {
        byte[] keyBytes = Base64.getDecoder().decode(keyString);
        return getKeyFromBytes(keyBytes);
    }
    /**
     * 生成随机IV
     */
    public static byte[] generateIv() {
        byte[] iv = new byte[IV_LENGTH];
        new SecureRandom().nextBytes(iv);
        return iv;
    }
    /**
     * 加密
     */
    public static String encrypt(String data, SecretKey key, byte[] iv) throws Exception {
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
        cipher.init(Cipher.ENCRYPT_MODE, key, ivParameterSpec);
        byte[] encrypted = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
        // 将IV和加密数据合并 (IV不需要保密,但需要与密文一起保存)
        byte[] combined = new byte[iv.length + encrypted.length];
        System.arraycopy(iv, 0, combined, 0, iv.length);
        System.arraycopy(encrypted, 0, combined, iv.length, encrypted.length);
        return Base64.getEncoder().encodeToString(combined);
    }
    /**
     * 解密
     */
    public static String decrypt(String encryptedData, SecretKey key) throws Exception {
        byte[] combined = Base64.getDecoder().decode(encryptedData);
        // 提取IV (前16字节)
        byte[] iv = new byte[IV_LENGTH];
        System.arraycopy(combined, 0, iv, 0, iv.length);
        // 提取加密数据 (剩余字节)
        byte[] encrypted = new byte[combined.length - iv.length];
        System.arraycopy(combined, iv.length, encrypted, 0, encrypted.length);
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
        cipher.init(Cipher.DECRYPT_MODE, key, ivParameterSpec);
        byte[] decrypted = cipher.doFinal(encrypted);
        return new String(decrypted, StandardCharsets.UTF_8);
    }
    public static void main(String[] args) throws Exception {
        // 生成密钥
        SecretKey key = generateKey();
        String keyString = Base64.getEncoder().encodeToString(key.getEncoded());
        System.out.println("生成的密钥: " + keyString);
        // 生成IV
        byte[] iv = generateIv();
        // 原始数据
        String originalData = "这是一个需要加密的敏感信息";
        System.out.println("原始数据: " + originalData);
        // 加密
        String encrypted = encrypt(originalData, key, iv);
        System.out.println("加密后: " + encrypted);
        // 解密
        String decrypted = decrypt(encrypted, key);
        System.out.println("解密后: " + decrypted);
    }
}

使用固定密钥的简化版本

如果需要使用固定的密钥(不推荐用于生产环境,仅用于演示):

public class AES256FixedKeyExample {
    private static final String FIXED_KEY = "ThisIsA32ByteLongFixedKey123"; // 必须是32字节长度
    private static final String ALGORITHM = "AES/CBC/PKCS5Padding";
    public static String encrypt(String data) throws Exception {
        SecretKeySpec keySpec = new SecretKeySpec(FIXED_KEY.getBytes(StandardCharsets.UTF_8), "AES");
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        // 生成随机IV
        byte[] iv = new byte[16];
        new SecureRandom().nextBytes(iv);
        IvParameterSpec ivSpec = new IvParameterSpec(iv);
        cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
        byte[] encrypted = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
        // 合并IV和密文
        byte[] combined = new byte[iv.length + encrypted.length];
        System.arraycopy(iv, 0, combined, 0, iv.length);
        System.arraycopy(encrypted, 0, combined, iv.length, encrypted.length);
        return Base64.getEncoder().encodeToString(combined);
    }
    public static String decrypt(String encryptedData) throws Exception {
        byte[] combined = Base64.getDecoder().decode(encryptedData);
        // 提取IV
        byte[] iv = new byte[16];
        System.arraycopy(combined, 0, iv, 0, iv.length);
        // 提取密文
        byte[] encrypted = new byte[combined.length - 16];
        System.arraycopy(combined, 16, encrypted, 0, encrypted.length);
        SecretKeySpec keySpec = new SecretKeySpec(FIXED_KEY.getBytes(StandardCharsets.UTF_8), "AES");
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        IvParameterSpec ivSpec = new IvParameterSpec(iv);
        cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
        byte[] decrypted = cipher.doFinal(encrypted);
        return new String(decrypted, StandardCharsets.UTF_8);
    }
}

注意事项

  1. 密钥管理:生产环境中不应硬编码密钥,应使用密钥管理系统或从安全位置加载
  2. IV处理:IV不需要保密,但必须与密文一起保存,且每次加密应使用不同的IV
  3. 填充方式:PKCS5Padding是常用的填充方式,确保数据长度是AES块大小的整数倍
  4. 异常处理:实际应用中应妥善处理所有可能的异常
  5. 性能考虑:对于大量数据,考虑使用流式加密而非一次性加密整个数据

推荐的密钥存储方式

对于生产环境,建议:

// 从环境变量或配置文件中读取密钥
String keyFromConfig = System.getenv("AES_ENCRYPTION_KEY");
SecretKey key = AES256Util.getKeyFromString(keyFromConfig);

确保密钥存储在安全的位置,如密钥管理服务、环境变量或加密的配置文件中。

Java AES256加密如何实现?-图2
(图片来源网络,侵删)
分享:
扫描分享到社交APP
上一篇
下一篇