java AES加密/解密实现完整代码(附带源码)

 更新时间:2025年04月30日 09:28:54   作者:Katie。  
这篇文章主要介绍了java AES加密/解密实现的相关资料,包括AES加密算法的基本原理、Java加密API的使用方法以及项目实现的步骤和代码示例,需要的朋友可以参考下

1. 项目背景与介绍

在数据传输和存储过程中,保护敏感信息的安全性非常关键。AES(Advanced Encryption Standard,高级加密标准)是一种广泛使用的对称加密算法,具有高效、安全、易于实现等特点。由于 AES 使用同一个密钥进行加密和解密,因此密钥的管理非常重要。

本项目将通过 Java 内置的加密 API(主要在 javax.crypto 包中提供)实现 AES 加密与解密。示例中我们采用 AES/CBC/PKCS5Padding 模式,并使用一个 128 位(16 字节)的密钥和固定的初始向量(IV)。为了便于演示,本示例使用了固定的 IV,但在实际应用中,建议使用随机 IV,并将 IV 与密文一起存储或传输。

通过本项目,你将掌握如何使用 Java 进行 AES 加密和解密操作,并了解如何对密钥和初始向量进行设置、Base64 编码结果输出等知识点。

2. 相关知识

2.1 AES 加密算法

  • 对称加密:AES 算法属于对称加密算法,即加密和解密使用相同的密钥。其优点是速度快,适合大数据量加密;缺点是密钥传输和管理存在一定风险。
  • 加密模式与填充方式:常用的模式有 ECB、CBC、CFB 等,本示例采用 CBC 模式。由于 AES 的块大小为 16 字节,当明文长度不是 16 字节的整数倍时,需要采用填充方式,本示例采用 PKCS5Padding。
  • 初始向量(IV):在 CBC 模式下,初始向量用于增加加密随机性,通常需要随机生成并与密文一起存储。但本示例为了简化演示,使用了固定的 IV(仅供学习参考)。

2.2 Java 加密 API

Java 提供了一整套加密相关的类:

  • Cipher:核心加密解密类,用于执行加密和解密操作。
  • SecretKeySpec:将原始密钥数据封装为密钥对象。
  • IvParameterSpec:封装初始向量数据。
  • Base64:用于将二进制数据转换为可读的字符串格式,便于传输和存储。

3. 项目实现思路

本项目主要分为以下几个步骤:

  • 准备密钥和初始向量定义 AES 加密所需的 128 位密钥和 16 字节的初始向量(IV)。在实际应用中,这些应由安全随机数生成器产生,并妥善管理。

  • 创建 Cipher 对象使用 Cipher.getInstance("AES/CBC/PKCS5Padding") 获取 Cipher 对象,并分别用密钥和 IV 初始化加密和解密模式。

  • 执行加密和解密操作

    • 加密:将明文字符串转换为字节数组,调用 doFinal() 方法获得密文字节数组,再进行 Base64 编码。
    • 解密:将 Base64 解码后的密文字节数组通过 doFinal() 方法还原为明文字节数组,并转换为字符串。
  • 整合代码并测试将上述流程封装到一个 Java 类中,在主函数中调用加密和解密方法,验证加解密是否正确。

4. 完整代码实现

下面是一份完整的 Java 代码示例,实现了 AES 加密与解密功能。代码中附有详细中文注释,便于理解每个步骤的实现细节。

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.spec.IvParameterSpec;
import java.util.Base64;

/**
 * AESEncryptionDemo 类演示了如何使用 Java 实现 AES 加密和解密。
 * 本示例使用 AES/CBC/PKCS5Padding 模式,密钥和初始向量均为 16 字节(128 位)。
 * 注意:示例中使用固定 IV 仅供学习,实际应用中应使用随机 IV 并与密文一起传输。
 */
public class AESEncryptionDemo {

    // AES 密钥(16 字节):请确保密钥足够随机和安全
    private static final String KEY = "0123456789abcdef";
    // 初始向量(IV,16 字节):实际应用中应随机生成
    private static final String IV = "abcdefghijklmnop";
    // 指定加密算法和模式
    private static final String ALGORITHM = "AES/CBC/PKCS5Padding";

    /**
     * 对给定的明文进行 AES 加密,并返回 Base64 编码后的密文字符串。
     *
     * @param plainText 明文字符串
     * @return Base64 编码后的密文字符串,如果加密过程中发生异常则返回 null
     */
    public static String encrypt(String plainText) {
        try {
            // 获取 Cipher 实例,指定使用 AES/CBC/PKCS5Padding 模式
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            // 构造密钥规范
            SecretKeySpec keySpec = new SecretKeySpec(KEY.getBytes("UTF-8"), "AES");
            // 构造初始向量规范
            IvParameterSpec ivSpec = new IvParameterSpec(IV.getBytes("UTF-8"));
            // 初始化 Cipher 为加密模式
            cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
            // 对明文进行加密
            byte[] encryptedBytes = cipher.doFinal(plainText.getBytes("UTF-8"));
            // 使用 Base64 对密文字节数组进行编码,返回字符串
            return Base64.getEncoder().encodeToString(encryptedBytes);
        } catch (Exception e) {
            // 捕获异常并打印错误信息
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 对给定的 Base64 编码密文进行 AES 解密,还原出原始明文字符串。
     *
     * @param cipherText Base64 编码后的密文字符串
     * @return 解密后的明文字符串,如果解密过程中发生异常则返回 null
     */
    public static String decrypt(String cipherText) {
        try {
            // 获取 Cipher 实例,指定使用 AES/CBC/PKCS5Padding 模式
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            // 构造密钥规范
            SecretKeySpec keySpec = new SecretKeySpec(KEY.getBytes("UTF-8"), "AES");
            // 构造初始向量规范
            IvParameterSpec ivSpec = new IvParameterSpec(IV.getBytes("UTF-8"));
            // 初始化 Cipher 为解密模式
            cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
            // 将 Base64 编码的密文转换为字节数组
            byte[] decodedBytes = Base64.getDecoder().decode(cipherText);
            // 对密文进行解密
            byte[] decryptedBytes = cipher.doFinal(decodedBytes);
            // 将解密后的字节数组转换为字符串
            return new String(decryptedBytes, "UTF-8");
        } catch (Exception e) {
            // 捕获异常并打印错误信息
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 主函数,演示 AES 加密和解密的完整流程。
     *
     * @param args 命令行参数(未使用)
     */
    public static void main(String[] args) {
        // 定义待加密的明文
        String plainText = "Hello, AES Encryption!";
        System.out.println("原始明文: " + plainText);

        // 对明文进行加密
        String encryptedText = encrypt(plainText);
        System.out.println("加密后的密文 (Base64 编码): " + encryptedText);

        // 对密文进行解密
        String decryptedText = decrypt(encryptedText);
        System.out.println("解密后的明文: " + decryptedText);
    }
}

5. 代码解读

5.1 密钥和初始向量设置

  • KEY 和 IV
    • 本示例中密钥和初始向量均为固定字符串,长度均为 16 字节,适用于 AES-128。
    • 实际应用中,应使用安全随机数生成密钥和 IV,并对 IV 进行传输或存储(例如,将 IV 附加在密文前)。

5.2 加密过程

  • Cipher 获取与初始化使用 Cipher.getInstance("AES/CBC/PKCS5Padding") 获取 Cipher 对象,并利用 SecretKeySpec 和 IvParameterSpec 初始化 Cipher 为加密模式。
  • 数据加密将明文转换为字节数组后调用 doFinal() 方法进行加密,生成密文字节数组;之后使用 Base64 编码便于输出和存储。

5.3 解密过程

  • Cipher 初始化为解密模式同样使用 SecretKeySpec 和 IvParameterSpec 初始化 Cipher 为解密模式。
  • 数据解密将 Base64 解码后的密文字节数组传入 doFinal() 方法进行解密,还原出原始明文字节数组,再转换为字符串。

5.4 异常处理

  • 在加密和解密过程中均使用 try-catch 捕获可能出现的异常,并输出堆栈信息,确保程序调试和排查问题时能获得足够的信息。

6. 项目总结与展望

本项目通过 Java 实现了 AES 加密和解密的基本流程,主要收获和体会包括:

  • 掌握对称加密基本原理学习了如何使用同一密钥对数据进行加密和解密,并理解了 AES 加密中密钥与初始向量的重要性。

  • 熟悉 Java 加密 API通过 Cipher、SecretKeySpec、IvParameterSpec 等类的使用,掌握了 Java 内置加密工具的基本操作。

  • 安全性与实际应用虽然本示例使用固定的 IV 仅供学习,但在实际应用中应采用随机 IV 并妥善管理密钥,确保数据加密安全性。

  • 扩展与优化方向

    • 可改进为生成随机 IV,并将 IV 与密文组合(例如将 IV 前置于密文中一起传输)。
    • 可以使用更高位数的 AES 加密(如 AES-256),前提是环境支持。
    • 将加密/解密过程封装为工具类,便于在实际项目中复用和集成。

总之,本项目为开发者提供了一个简单、直观的 AES 加密/解密示例,既有助于理解对称加密的基本流程,也为构建实际安全通信系统提供了实践基础。希望这篇博客文章能为你在 Java 安全编程领域提供有价值的参考和启发。

总结

到此这篇关于java AES加密/解密实现的文章就介绍到这了,更多相关java AES加密解密内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 教你轻松制作java视频播放器

    教你轻松制作java视频播放器

    这篇文章主要为大家详细介绍了如何编写属于自己的java视频播放器,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-06-06
  • IDEA中使用Docker Compose容器编排的实现

    IDEA中使用Docker Compose容器编排的实现

    这篇文章主要介绍了IDEA中使用Docker Compose容器编排的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07
  • 基于java servlet过滤器和监听器(详解)

    基于java servlet过滤器和监听器(详解)

    下面小编就为大家带来一篇基于java servlet过滤器和监听器(详解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-10-10
  • Spring Cloud Alibaba 之 Nacos教程详解

    Spring Cloud Alibaba 之 Nacos教程详解

    Nacos是阿里的一个开源产品,它是针对微服务架构中的服务发现、配置管理、服务治理的综合性解决方案。这篇文章主要介绍了Spring Cloud Alibaba 之 Nacos的相关知识,需要的朋友可以参考下
    2020-11-11
  • Java实现发送邮件功能时碰到的坑

    Java实现发送邮件功能时碰到的坑

    之前用163邮箱发邮件时明明是成功的,但是使用中国移动自己的邮箱时,无论如何在linux服务器中都发送不成功。下面小编给大家说下我是怎么解决的,一起看下吧
    2016-06-06
  • spring boot使用自定义的线程池执行Async任务

    spring boot使用自定义的线程池执行Async任务

    这篇文章主要介绍了spring boot使用自定义的线程池执行Async任务的相关资料,需要的朋友可以参考下
    2018-02-02
  • Spring Boot构建框架详解

    Spring Boot构建框架详解

    这篇文章主要为大家详细介绍了Spring Boot构建框架的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-10-10
  • spring boot自定义配置时在yml文件输入有提示问题及解决方案

    spring boot自定义配置时在yml文件输入有提示问题及解决方案

    自定义一个配置类,然后在yml文件具体配置值时,一般不会有提示,今天小编给大家分享spring boot自定义配置时在yml文件输入有提示问题,感兴趣的朋友一起看看吧
    2023-10-10
  • Java删除ArrayList中的重复元素的两种方法

    Java删除ArrayList中的重复元素的两种方法

    在Java编程中,ArrayList是一种常用的集合类,它允许我们存储一组元素,在某些情况下,我们可能需要移除其中重复的元素,只保留唯一的元素,下面介绍两种常见的删除ArrayList中重复元素的方法,需要的朋友可以参考下
    2024-12-12
  • SpringBoot 实现自定义的 @ConditionalOnXXX 注解示例详解

    SpringBoot 实现自定义的 @ConditionalOnXXX 注解示例详解

    这篇文章主要介绍了SpringBoot 实现自定义的 @ConditionalOnXXX 注解,通过示例代码介绍了实现一个自定义的 @Conditional 派生注解,Conditional 派生注解的类如何注入到 spring 容器,需要的朋友可以参考下
    2022-08-08

最新评论