0

0

Java中如何用AES实现数据加密解密

下次还敢

下次还敢

发布时间:2025-06-28 22:42:02

|

634人浏览过

|

来源于php中文网

原创

aes加密在java中通过密钥进行数据加密和解密。1. 选择密钥长度时,128位适用于大多数场景,高安全性需求可选192位或256位;2. 处理大文件需分块加密,使用cipher.update()处理数据块,cipher.dofinal()处理剩余数据;3. 密钥管理方式包括keystore、hsm、kms、pbkdf2和ecdh,根据安全需求和预算选择。

Java中如何用AES实现数据加密解密

AES加密解密在Java里其实挺常见的,简单来说,就是用一个密钥把数据变成乱码,然后再用同样的密钥还原回去。用得好的话,能有效保护数据安全。

Java中如何用AES实现数据加密解密

直接上代码,先看怎么用AES加密解密字符串:

Java中如何用AES实现数据加密解密
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

public class AESUtil {

    private static final String ALGORITHM = "AES";
    private static final int KEY_SIZE = 128; // 可以是 128, 192, 或 256

    // 生成密钥
    public static SecretKey generateKey() throws NoSuchAlgorithmException {
        KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM);
        keyGenerator.init(KEY_SIZE);
        return keyGenerator.generateKey();
    }

    // 密钥转为Base64字符串(方便存储和传输)
    public static String secretKeyToBase64(SecretKey secretKey) {
        byte[] encoded = secretKey.getEncoded();
        return Base64.getEncoder().encodeToString(encoded);
    }

    // Base64字符串转回密钥
    public static SecretKey base64ToSecretKey(String base64Key) {
        byte[] decodedKey = Base64.getDecoder().decode(base64Key);
        return new SecretKeySpec(decodedKey, 0, decodedKey.length, ALGORITHM);
    }


    // 加密
    public static String encrypt(String data, SecretKey secretKey) throws Exception {
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        byte[] encryptedBytes = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }

    // 解密
    public static String decrypt(String encryptedData, SecretKey secretKey) throws Exception {
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        byte[] decodedBytes = Base64.getDecoder().decode(encryptedData);
        byte[] decryptedBytes = cipher.doFinal(decodedBytes);
        return new String(decryptedBytes, StandardCharsets.UTF_8);
    }

    public static void main(String[] args) throws Exception {
        SecretKey secretKey = generateKey();
        String originalString = "This is a secret message!";
        String encryptedString = encrypt(originalString, secretKey);
        String decryptedString = decrypt(encryptedString, secretKey);

        System.out.println("Original String: " + originalString);
        System.out.println("Encrypted String: " + encryptedString);
        System.out.println("Decrypted String: " + decryptedString);

        // 密钥的Base64存储示例
        String base64Key = secretKeyToBase64(secretKey);
        System.out.println("Secret Key (Base64): " + base64Key);
        SecretKey restoredKey = base64ToSecretKey(base64Key);
        System.out.println("Restored Key equals Original Key: " + secretKey.equals(restoredKey));
    }
}

如何选择合适的AES密钥长度?

AES密钥长度通常有128位、192位和256位三种选择。密钥越长,安全性越高,但同时计算复杂度也会增加。128位密钥对于大多数应用来说已经足够安全。 如果你的数据安全性要求非常高,例如需要保护银行交易信息或国家机密,那么可以考虑使用192位或256位密钥。密钥长度的选择需要在安全性和性能之间进行权衡。一般来说,128位密钥是一个不错的折中方案。

立即学习Java免费学习笔记(深入)”;

51shop 网上商城系统
51shop 网上商城系统

51shop 由 PHP 语言开发, 使用快速的 MySQL 数据库保存数据 ,为中小型网站实现网上电子商务提供一个完美的解决方案.一、用户模块1. 用户注册:用户信息包括:用户ID、用户名、用户密码、性别、邮箱、省份、城市、 联系电话等信息,用户注册后不能立即使用,需由管理员激活账号,才可使用(此功能管理员可设置)2. 登录功能3. 资料修改:用户可修改除账号以后的所有资料4. 忘记密码:要求用

下载

加密文件时如何处理大文件?

直接把整个大文件读到内存里加密肯定不行,容易OOM。 正确姿势是分块加密。

Java中如何用AES实现数据加密解密
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

public class AESFileUtil {

    private static final String ALGORITHM = "AES";
    private static final int KEY_SIZE = 128;
    private static final int BUFFER_SIZE = 8192; // 8KB 缓冲区

    public static SecretKey generateKey() throws NoSuchAlgorithmException {
        KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM);
        keyGenerator.init(KEY_SIZE);
        return keyGenerator.generateKey();
    }

    public static void encryptFile(String inputFile, String outputFile, SecretKey secretKey) throws Exception {
        try (FileInputStream fis = new FileInputStream(inputFile);
             FileOutputStream fos = new FileOutputStream(outputFile)) {

            Cipher cipher = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);

            byte[] buffer = new byte[BUFFER_SIZE];
            int bytesRead;
            while ((bytesRead = fis.read(buffer)) != -1) {
                byte[] output = cipher.update(buffer, 0, bytesRead);
                if (output != null) {
                    fos.write(output);
                }
            }
            byte[] outputBytes = cipher.doFinal(); // 处理剩余数据
            if (outputBytes != null) {
                fos.write(outputBytes);
            }
        }
    }

    public static void decryptFile(String inputFile, String outputFile, SecretKey secretKey) throws Exception {
        try (FileInputStream fis = new FileInputStream(inputFile);
             FileOutputStream fos = new FileOutputStream(outputFile)) {

            Cipher cipher = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, secretKey);

            byte[] buffer = new byte[BUFFER_SIZE];
            int bytesRead;
            while ((bytesRead = fis.read(buffer)) != -1) {
                byte[] output = cipher.update(buffer, 0, bytesRead);
                if (output != null) {
                    fos.write(output);
                }
            }
            byte[] outputBytes = cipher.doFinal(); // 处理剩余数据
            if (outputBytes != null) {
                fos.write(outputBytes);
            }
        }
    }


    public static void main(String[] args) throws Exception {
        SecretKey secretKey = generateKey();
        String inputFile = "original.txt"; // 替换成你的输入文件
        String encryptedFile = "encrypted.txt";
        String decryptedFile = "decrypted.txt";

        // 创建一个示例文件
        try (FileOutputStream fos = new FileOutputStream(inputFile)) {
            fos.write("This is a sample file for encryption.".getBytes());
        }

        encryptFile(inputFile, encryptedFile, secretKey);
        System.out.println("File encrypted successfully!");

        decryptFile(encryptedFile, decryptedFile, secretKey);
        System.out.println("File decrypted successfully!");
    }
}

核心在于cipher.update()cipher.doFinal()这两个方法。update()方法用于处理分块数据,而doFinal()方法用于处理最后一块数据,完成加密或解密过程。

除了直接使用SecretKey,还有没有其他密钥管理方式?

当然有。直接在代码里写死密钥或者简单存储SecretKey是很不安全的。 常见的密钥管理方式包括:

  • 使用密钥库(KeyStore): Java提供了KeyStore类来安全地存储密钥和证书。你可以将密钥存储在KeyStore中,并使用密码保护它。
  • 使用硬件安全模块(HSM): HSM是一种专门用于存储和管理密钥的硬件设备。HSM提供了更高的安全性,可以防止密钥被窃取。
  • 使用密钥管理系统(KMS): KMS是一种集中式的密钥管理服务,可以让你安全地存储、管理和使用密钥。云服务提供商通常提供KMS服务,例如AWS KMS、Azure Key Vault等。
  • 使用口令派生密钥(PBKDF2): PBKDF2算法可以使用用户提供的口令生成密钥。这种方式可以避免直接存储密钥,但安全性取决于口令的强度。
  • 使用椭圆曲线Diffie-Hellman (ECDH): 这种方法允许双方在不安全通道上协商共享密钥。

选择哪种密钥管理方式取决于你的安全需求和预算。一般来说,对于高安全性的应用,建议使用HSM或KMS。对于安全性要求较低的应用,可以使用KeyStore或PBKDF2。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

760

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

220

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1564

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

649

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

1208

2024.03.22

php中定义字符串的方式
php中定义字符串的方式

php中定义字符串的方式:单引号;双引号;heredoc语法等等。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

1184

2024.04.29

go语言字符串相关教程
go语言字符串相关教程

本专题整合了go语言字符串相关教程,阅读专题下面的文章了解更多详细内容。

192

2025.07.29

c++字符串相关教程
c++字符串相关教程

本专题整合了c++字符串相关教程,阅读专题下面的文章了解更多详细内容。

131

2025.08.07

Go高并发任务调度与Goroutine池化实践
Go高并发任务调度与Goroutine池化实践

本专题围绕 Go 语言在高并发任务处理场景中的实践展开,系统讲解 Goroutine 调度模型、Channel 通信机制以及并发控制策略。内容包括任务队列设计、Goroutine 池化管理、资源限制控制以及并发任务的性能优化方法。通过实际案例演示,帮助开发者构建稳定高效的 Go 并发任务处理系统,提高系统在高负载环境下的处理能力与稳定性。

4

2026.03.10

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL 教程
PostgreSQL 教程

共48课时 | 10.5万人学习

Django 教程
Django 教程

共28课时 | 4.9万人学习

Excel 教程
Excel 教程

共162课时 | 20.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号