Java案例如何实现AES加密?

wen java案例 67

本文目录导读:

Java案例如何实现AES加密?

  1. 基础AES加密解密案例
  2. 带IV向量的CBC模式(更安全)
  3. 使用固定密钥(字符串转密钥)
  4. 完整工具类(推荐使用)
  5. 注意事项

在Java中实现AES加密,通常使用javax.crypto包中的Cipher类,以下是一个完整的AES加密解密案例,包括随机生成密钥、加密字符串和解密字符串的功能。

基础AES加密解密案例

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.SecureRandom;
import java.util.Base64;
public class AESExample {
    // 加密算法
    private static final String ALGORITHM = "AES";
    // 加密填充模式(AES/ECB/PKCS5Padding 是最常用模式)
    private static final String TRANSFORMATION = "AES/ECB/PKCS5Padding";
    public static void main(String[] args) throws Exception {
        // 1. 生成密钥
        SecretKey secretKey = generateAESKey(128);
        // 2. 待加密的原文
        String originalText = "Hello, 这是需要加密的敏感信息!";
        System.out.println("原文:" + originalText);
        // 3. 加密
        String encryptedText = encrypt(originalText, secretKey);
        System.out.println("密文:" + encryptedText);
        // 4. 解密
        String decryptedText = decrypt(encryptedText, secretKey);
        System.out.println("解密后:" + decryptedText);
        // 验证
        System.out.println("加密解密是否成功:" + originalText.equals(decryptedText));
    }
    /**
     * 生成AES密钥
     * @param keySize 密钥长度(128, 192, 256)
     * @return SecretKey对象
     */
    public static SecretKey generateAESKey(int keySize) throws Exception {
        KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM);
        keyGenerator.init(keySize);
        return keyGenerator.generateKey();
    }
    /**
     * 加密
     * @param plainText 明文
     * @param secretKey 密钥
     * @return Base64编码的密文
     */
    public static String encrypt(String plainText, SecretKey secretKey) throws Exception {
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        byte[] encryptedBytes = cipher.doFinal(plainText.getBytes("UTF-8"));
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }
    /**
     * 解密
     * @param encryptedText Base64编码的密文
     * @param secretKey 密钥
     * @return 明文
     */
    public static String decrypt(String encryptedText, SecretKey secretKey) throws Exception {
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedText));
        return new String(decryptedBytes, "UTF-8");
    }
}

带IV向量的CBC模式(更安全)

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.SecureRandom;
import java.util.Base64;
public class AESCBCExample {
    // AES/CBC/PKCS5Padding 模式更安全
    private static final String TRANSFORMATION = "AES/CBC/PKCS5Padding";
    private static final String ALGORITHM = "AES";
    public static void main(String[] args) throws Exception {
        // 生成密钥
        SecretKey secretKey = generateAESKey(128);
        // 生成随机IV
        IvParameterSpec iv = generateIV();
        String originalText = "这是需要加密的敏感信息,使用CBC模式!";
        System.out.println("原文:" + originalText);
        // 加密(需要同时保存密钥和IV)
        String encryptedText = encrypt(originalText, secretKey, iv);
        System.out.println("密文:" + encryptedText);
        // 解密
        String decryptedText = decrypt(encryptedText, secretKey, iv);
        System.out.println("解密后:" + decryptedText);
    }
    /**
     * 生成AES密钥
     */
    public static SecretKey generateAESKey(int keySize) throws Exception {
        KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM);
        keyGenerator.init(keySize);
        return keyGenerator.generateKey();
    }
    /**
     * 生成IV(初始化向量)
     */
    public static IvParameterSpec generateIV() {
        byte[] iv = new byte[16]; // AES块大小为128位(16字节)
        new SecureRandom().nextBytes(iv);
        return new IvParameterSpec(iv);
    }
    /**
     * 加密(CBC模式)
     */
    public static String encrypt(String plainText, SecretKey secretKey, IvParameterSpec iv) throws Exception {
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
        byte[] encryptedBytes = cipher.doFinal(plainText.getBytes("UTF-8"));
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }
    /**
     * 解密(CBC模式)
     */
    public static String decrypt(String encryptedText, SecretKey secretKey, IvParameterSpec iv) throws Exception {
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);
        byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedText));
        return new String(decryptedBytes, "UTF-8");
    }
}

使用固定密钥(字符串转密钥)

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
import java.util.Base64;
public class AESWithFixedKey {
    private static final String ALGORITHM = "AES";
    // ECB模式不需要IV
    private static final String TRANSFORMATION = "AES/ECB/PKCS5Padding";
    public static void main(String[] args) throws Exception {
        // 固定密钥字符串(需要16、24或32字节)
        String keyString = "ThisIsASecretKey1234567890"; // 24字节
        // 将字符串转换为密钥
        SecretKeySpec secretKey = new SecretKeySpec(keyString.getBytes("UTF-8"), ALGORITHM);
        String originalText = "使用固定密钥进行AES加密!";
        System.out.println("原文:" + originalText);
        // 加密
        String encryptedText = encrypt(originalText, secretKey);
        System.out.println("密文:" + encryptedText);
        // 解密
        String decryptedText = decrypt(encryptedText, secretKey);
        System.out.println("解密后:" + decryptedText);
    }
    public static String encrypt(String plainText, SecretKeySpec secretKey) throws Exception {
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        byte[] encryptedBytes = cipher.doFinal(plainText.getBytes("UTF-8"));
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }
    public static String decrypt(String encryptedText, SecretKeySpec secretKey) throws Exception {
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedText));
        return new String(decryptedBytes, "UTF-8");
    }
}

完整工具类(推荐使用)

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.SecureRandom;
import java.util.Base64;
public class AESUtils {
    private static final String ALGORITHM = "AES";
    private static final String TRANSFORMATION = "AES/CBC/PKCS5Padding";
    private static final int KEY_SIZE = 128;
    /**
     * 生成密钥
     */
    public static SecretKey generateKey() throws Exception {
        KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM);
        keyGenerator.init(KEY_SIZE);
        return keyGenerator.generateKey();
    }
    /**
     * 生成IV
     */
    public static IvParameterSpec generateIV() {
        byte[] iv = new byte[16];
        new SecureRandom().nextBytes(iv);
        return new IvParameterSpec(iv);
    }
    /**
     * 加密(返回Base64编码)
     */
    public static String encrypt(String plainText, SecretKey key, IvParameterSpec iv) throws Exception {
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        cipher.init(Cipher.ENCRYPT_MODE, key, iv);
        byte[] encrypted = cipher.doFinal(plainText.getBytes("UTF-8"));
        return Base64.getEncoder().encodeToString(encrypted);
    }
    /**
     * 解密
     */
    public static String decrypt(String encryptedText, SecretKey key, IvParameterSpec iv) throws Exception {
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        cipher.init(Cipher.DECRYPT_MODE, key, iv);
        byte[] decrypted = cipher.doFinal(Base64.getDecoder().decode(encryptedText));
        return new String(decrypted, "UTF-8");
    }
    /**
     * 将密钥转换为Base64字符串
     */
    public static String keyToString(SecretKey key) {
        return Base64.getEncoder().encodeToString(key.getEncoded());
    }
    /**
     * 将Base64字符串转换为密钥
     */
    public static SecretKey stringToKey(String keyStr) {
        byte[] decodedKey = Base64.getDecoder().decode(keyStr);
        return new SecretKeySpec(decodedKey, 0, decodedKey.length, ALGORITHM);
    }
    /**
     * 将IV转换为Base64字符串
     */
    public static String ivToString(IvParameterSpec iv) {
        return Base64.getEncoder().encodeToString(iv.getIV());
    }
    /**
     * 将Base64字符串转换为IV
     */
    public static IvParameterSpec stringToIV(String ivStr) {
        byte[] iv = Base64.getDecoder().decode(ivStr);
        return new IvParameterSpec(iv);
    }
    public static void main(String[] args) throws Exception {
        // 使用示例
        SecretKey key = generateKey();
        IvParameterSpec iv = generateIV();
        String original = "测试AES加密解密功能!";
        System.out.println("原文:" + original);
        // 加密
        String encrypted = encrypt(original, key, iv);
        System.out.println("密文:" + encrypted);
        // 解密
        String decrypted = decrypt(encrypted, key, iv);
        System.out.println("解密后:" + decrypted);
        // 密钥持久化示例
        String keyStr = keyToString(key);
        String ivStr = ivToString(iv);
        System.out.println("密钥(Base64):" + keyStr);
        System.out.println("IV(Base64):" + ivStr);
        // 从字符串恢复密钥和IV
        SecretKey restoredKey = stringToKey(keyStr);
        IvParameterSpec restoredIv = stringToIV(ivStr);
        String decrypted2 = decrypt(encrypted, restoredKey, restoredIv);
        System.out.println("恢复密钥解密:" + decrypted2);
    }
}

注意事项

  1. 密钥长度:AES支持128、192、256位密钥,256位需要安装Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy文件。

  2. 模式选择

    • ECB模式:简单但安全性较低,相同明文生成相同密文
    • CBC模式:需要IV向量,更安全,推荐使用
  3. 填充方式:PKCS5Padding是最常用的填充方式

  4. IV向量:CBC模式下每次加密都应使用不同的随机IV,IV不需要保密,但要保存

  5. 密钥管理:实际应用中,密钥应安全存储,不要硬编码在代码中

  6. 异常处理:实际应用中应添加适当的异常处理

这样你就可以在Java中轻松实现AES加密和解密了!

抱歉,评论功能暂时关闭!