Java实现对称加密算法-AES加解密

2023-11-11

AES(Advanced Encryption Standard)意思是高级加密标准,是一种区块加密标准。这个标准用来替代原先的DES,且已经被广泛使用。

DES使用56位密钥,所以比较容易被破解。

AES可以使用128、192、和256位密钥,并且用128位分组加密和解密数据,相对来说安全很多。

完善的加密算法在理论上是无法破解的,除非使用穷尽法(也称暴力破解)。使用穷尽法破解密钥长度在128位以上的加密数据是不现实的,仅存在理论上的可能性。统计显示,即使使用目前世界上运算速度最快的计算机,穷尽128位密钥也要花上几十亿年的时间,更不用说去破解采用256位密钥长度的AES算法了。

AES是一种对称加密算法,也就是加密和解密使用的是同一把秘钥。

Java实现AES:

import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.StringUtils;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.security.SecureRandom;


public class AESUtil {
    private static final String KEY_ALGORITHM = "AES";
    private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";

    /**
     * 指定随机字符串(密码)生成密钥
     *
     * @param randomKey 加解密的密码
     * @throws Exception
     */
    public static byte[] getSecretKey(String randomKey) throws Exception {
        KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_ALGORITHM); //秘钥生成器,指定秘钥算法

        //初始化此密钥生成器,指定AES的秘钥长度为128
        if (StringUtils.isBlank(randomKey)) {   //不指定密码
            keyGenerator.init(128);
        } else {    //指定密码
            SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
            random.setSeed(randomKey.getBytes());
            keyGenerator.init(128, random);
        }

        SecretKey secretKey = keyGenerator.generateKey();   //生成密钥
        return secretKey.getEncoded();
    }

    /**
     * 加密
     *
     * @param data 待加密数据
     * @param key  密钥
     * @return byte[]   加密数据
     * @throws Exception
     */
    public static byte[] encrypt(byte[] data, Key key) throws Exception {
        return encrypt(data, key, DEFAULT_CIPHER_ALGORITHM);
    }

    /**
     * 加密
     *
     * @param data 待加密数据
     * @param key  二进制密钥
     * @return byte[]   加密数据
     * @throws Exception
     */
    public static byte[] encrypt(byte[] data, byte[] key) throws Exception {
        return encrypt(data, key, DEFAULT_CIPHER_ALGORITHM);
    }

    /**
     * 加密
     *
     * @param data            待加密数据
     * @param key             二进制密钥
     * @param cipherAlgorithm 加密算法/工作模式/填充方式
     * @return byte[]   加密数据
     * @throws Exception
     */
    public static byte[] encrypt(byte[] data, byte[] key, String cipherAlgorithm) throws Exception {
        Key k = toKey(key);
        return encrypt(data, k, cipherAlgorithm);
    }

    /**
     * 加密
     *
     * @param data            待加密数据
     * @param key             密钥
     * @param cipherAlgorithm 加密算法/工作模式/填充方式
     * @return byte[]   加密数据
     * @throws Exception
     */
    public static byte[] encrypt(byte[] data, Key key, String cipherAlgorithm) throws Exception {
        Cipher cipher = Cipher.getInstance(cipherAlgorithm);    //获取算法
        cipher.init(Cipher.ENCRYPT_MODE, key);                  //设置加密模式,并指定秘钥
        return cipher.doFinal(data);                            //加密数据
    }

    /**
     * 解密
     *
     * @param data 待解密数据
     * @param key  二进制密钥
     * @return byte[]   解密数据
     * @throws Exception
     */
    public static byte[] decrypt(byte[] data, byte[] key) throws Exception {
        return decrypt(data, key, DEFAULT_CIPHER_ALGORITHM);
    }

    /**
     * 解密
     *
     * @param data 待解密数据
     * @param key  密钥
     * @return byte[]   解密数据
     * @throws Exception
     */
    public static byte[] decrypt(byte[] data, Key key) throws Exception {
        return decrypt(data, key, DEFAULT_CIPHER_ALGORITHM);
    }

    /**
     * 解密
     *
     * @param data            待解密数据
     * @param key             二进制密钥
     * @param cipherAlgorithm 加密算法/工作模式/填充方式
     * @return byte[]   解密数据
     * @throws Exception
     */
    public static byte[] decrypt(byte[] data, byte[] key, String cipherAlgorithm) throws Exception {
        Key k = toKey(key);
        return decrypt(data, k, cipherAlgorithm);
    }

    /**
     * 解密
     *
     * @param data            待解密数据
     * @param key             密钥
     * @param cipherAlgorithm 加密算法/工作模式/填充方式
     * @return byte[]   解密数据
     * @throws Exception
     */
    public static byte[] decrypt(byte[] data, Key key, String cipherAlgorithm) throws Exception {
        Cipher cipher = Cipher.getInstance(cipherAlgorithm);     //获取算法
        cipher.init(Cipher.DECRYPT_MODE, key);                   //设置解密模式,并指定秘钥
        return cipher.doFinal(data);                             //解密数据
    }

    /**
     * 转换密钥
     *
     * @param secretKey 二进制密钥
     * @return 密钥
     */
    public static Key toKey(byte[] secretKey) {
        return new SecretKeySpec(secretKey, KEY_ALGORITHM);   //生成密钥
    }


    public static void main(String[] args) throws Exception {
        String password = "123456";     //加解密的密码
        byte[] secretKey = getSecretKey(password);
        Key key = toKey(secretKey);

        String data = "AES 对称加密算法";
        System.out.println("明文 :" + data);

        byte[] encryptData = encrypt(data.getBytes(), key);
        String encryptDataHex = Hex.encodeHexString(encryptData);   //把密文转为16进制
        System.out.println("加密 : " + encryptDataHex);

        byte[] decryptData = decrypt(Hex.decodeHex(encryptDataHex.toCharArray()), key);
        System.out.println("解密 : " + new String(decryptData));
    }
}

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java实现对称加密算法-AES加解密 的相关文章

  • 如何在java swing中的每个页面中打印带有页脚的整个JPanel

    好吧 这可能很简单 但想不通 我有一个包含 JTable 的 JPanel JTable 包含很少的行 有时更多 因为我推入其中的表模型取决于数据库 但是 我不使用任何包含 JTable 的 JScolpane 因此 当 JTable 包含
  • 使用选项卡式活动中的捆绑包将值从活动传递到片段

    我是一个java文盲 但仍在尝试开发一个供我个人使用的应用程序 我从 android studio 的 Tabbed Activity 开始 除了 MainActivity 中的一个片段和一个包之外 大部分没有改变 这是我的代码 主要活动
  • Firebase 查询 Or'ing whereEqualTo 以获得可能值的列表

    我见过之前针对早期版本的 Firebase 提出过这个问题 https stackoverflow com questions 26700924 query based on multiple where clauses in fireba
  • JavaEE 8 教程,在 hello1 项目上部署失败

    我正在尝试学习 Java EE 8 我遵循了官方指南https javaee github io tutorial https javaee github io tutorial 但我有这个问题 cargo maven2 plugin 1
  • Java Swing:清除JList而不触发监听器

    我的情况如下 我有一个 JList 只要在列表中进行选择 它就会触发搜索 使用 ListSelectionListener 我正在尝试使用以下命令重置列表上的选择list clearSelection 这样做的问题是使用clearSelec
  • .java 和 .scala 类之间是否可能存在循环依赖?

    假设我在 java 文件中定义了类 A 在 scala 文件中定义了类 B A 类使用 B 类 B 类使用 A 类 如果我使用 java 编译器 则会出现编译错误 因为 B 类尚未编译 如果我使用scala编译器A类将找不到 有没有可以同时
  • 使用 jdbc 程序连接到 Open Office odb 文件

    我编写了以下代码来连接到 OpenOffice db String db C Documents and Settings hkonakanchi Desktop Test odb Class forName org hsqldb jdbc
  • JUnit 使用 Mockito 测试异步方法

    我已经使用 Spring Framework 版本 5 0 5 RELEASE 在 Java 1 8 类中实现了异步方法 public class ClassToBeTested Autowired private MyComponent
  • Maven + Cobertura:无法找到[您的班级]。你指定了源目录吗?

    我有 MyMath 类 有两个简单的方法 multi 和 add 和测试类只会测试多种方法 public class MainTest Test public void testMultiply MyMath tester new MyMa
  • 删除 servlet 中的 cookie 时出现问题

    我尝试使用以下代码删除 servlet 中的 cookie Cookie minIdCookie null for Cookie c req getCookies if c getName equals iPlanetDirectoryPr
  • Maven 多模块项目结构问题

    自从过去几周构建我的 Maven 多模块项目以来 这是我的一次有趣的经历 当我决定使用 Maven 进行构建生命周期管理时 我有几个原因希望选择 Maven A 大多数开发团队都是分开的 这样每个团队都可以在项目中的单独模块上工作 例如团队
  • 在 Spring 中设置 WS https 调用超时 (HttpsUrlConnectionMessageSender)

    我正在尝试为 WS 调用设置超时 我延长了WebServiceGatewaySupport并尝试将发送者超时设置为如下 public Object marshalSendAndReceive Object requestPayload We
  • LibGdx 如何使用 OrthographicCamera 滚动?

    我已经找了 10 个小时 字面意思 我已经完成了 我需要问一下 事情是我正在学习如何使用 LibGdx 来编写 Java 游戏 我正在做一个水平太空飞船游戏 所以 我最糟糕的问题是我不知道如何滚动 我认为绘制会更好地解释 我想绘制一个巨大的
  • Vertx HttpClient getNow 不工作

    我的 vertx HttpClient 有问题 下面的代码显示使用 vertx 和纯 java 测试 GET Vertx vertx Vertx vertx HttpClientOptions options new HttpClientO
  • Java中的DRY原则[关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 我一直在读关于DRY https en wikipedia org wiki Don 27t repeat yourself原则 虽然看起来
  • 哪种 Java DOM 包装器是最好或最受欢迎的? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 存储过程将多个表返回到 spring jdbc 模板

    我正在使用 JdbcTemplate 从 Spring DAO 类调用存储过程 我的问题是 存储过程返回多个表 有没有办法使用 Spring JdbcTemplate 访问多个表 如果我使用jdbcTemplate queryForList
  • 用 Java 创建迷宫求解算法

    我被分配了用 Java 创建迷宫求解器的任务 这是任务 Write an application that finds a path through a maze The maze should be read from a file A
  • 监控 Java 应用程序上的锁争用

    我正在尝试创建一个小基准 在 Groovy 中 以显示几个同步方法上的高线程争用 当监控自愿上下文切换时 应该会出现高争用 在 Linux 中 这可以通过 pidstat 来实现 程序如下 class Res private int n s
  • 如何使用 Spring AOP 建议静态方法?

    在执行类的静态方法之前和之后需要完成一些日志记录 我尝试使用 Spring AOP 来实现这一点 但它不起作用 而对于正常方法来说它起作用 请帮助我理解如何实现这一点 如果可以使用注释来完成 那就太好了 也许您应该在使用 Spring AO

随机推荐

  • Linus命令大全

    Linus命令是Linux操作系统中的一些常用命令 下面是一些常用的Linus命令 ls 用于显示当前目录中的文件和目录 cd 用于切换当前目录 pwd 显示当前目录的路径 mkdir 创建新目录 rm 删除文件或目录 cp 复制文件或目录
  • MoveIt入门之——使用MoveIt配置助手生成MoveIt配置文件

    一 安装MoveIt assistant sudo apt get install ros kinetic moveit 如果报错说找不到软件包 可能是没有更新源 只要去roswiki上找安装教程 把源重新加入就可以了 二 打开配置助手 r
  • npm ERR! code EPERM npm ERR! syscall unlink npm ERR!错误解决方法

    npm ERR code EPERM npm ERR syscall unlink npm ERR 错误解决方法 1 问题描述 2 解决方法 1 问题描述 由于之前电脑系统的原因 电脑重置了一下 之前安装的环境都没了 然后在重新安装node
  • 架构之重构的 12 条军规

    注 架构之重构的 12 条军规 上 发布以后 一些读者着急要下篇 所以在这里我把上下篇合并成一篇 让大家可以阅读完整版 不用分开看了 对于开发者来说 架构设计是软件研发过程中最重要的一环 所谓没有图纸 就建不了房子 在遍地 App 的互联网
  • 自学Python能做什么副业?通过这篇文章一起来看看

    很多小伙伴想在业余的时间自学一下python语言 但是又不知道python能够给自己带来什么 那么小编就通过这篇文章来和大家一起说说python学会了能做哪些副业 一 兼职处理数据 在目前的万物互联的时代下 越来越多的人离不开电脑 手机的办
  • 爬虫中的大哥大-scrapy框架介绍

    文章适合于所有的相关人士进行学习 各位看官看完了之后不要立刻转身呀 期待三连关注小小博主加收藏 小小博主回关快 会给你意想不到的惊喜呀 文章目录 scrapy介绍及安装 创建项目 创建爬虫 注意 如何运行 scrapy爬虫实战 1 sett
  • VMWare安装Ubuntu18时卡住

    VMWare安装Ubuntu18时卡住 今天安装Ubuntu时发现一直卡在 Started Network Manager Script Dispatcher Service 或者Mounting 的地方 由于点击安装之后没看 过了2小时看
  • Spring中获取Bean对象的三种注入方式和两种注入方法

    目录 前言 获取Bean对象的三种注入方式 属性注 构造 法注 Setter 注 属性注 构造 法注 和Setter 注 有什么区别呢 两种注入方法 Autowired 和 Resource Autowired 和 Resource 有什么
  • vue3 vite sass样式大量重复

    在vite config ts中配置 css preprocessorOptions 导入scss预编译程序 scss additionalData import assets scss variables scss import asse
  • Linux下修改IP、DNS、路由命令行设置

    一 快速修改 重启后设置就没了 ifconfig eth0 192 168 1 22 netmask 255 255 255 0 up route add default gw 192 168 1 2 二 修改配置文件 重启设置还在 一 u
  • LeetCode-2373. 矩阵中的局部最大值【矩阵,数组】

    LeetCode 2373 矩阵中的局部最大值 矩阵 数组 题目描述 解题思路一 原地修改 首先将每个3 3的矩阵的最大值存放在左上角的点 然后修改给的grid矩阵的大小 解题思路二 暴力 申请一个数组 解题思路三 0 题目描述 给你一个大
  • java8中常用函数式接口Supplier<T>、Consumer<T>、Function<T,R>、Predicate<T>使用示例

    场景 函数式接口 Functional Interface 就是一个有且仅有一个抽象方法 但是可以有多个非抽象方法的接口 而java中的函数式编程体现就是Lambda 所以函数式接口就是可以适用于Lambda使用的接口 下面介绍四个常用的函
  • 热议话题

    这两天在平台上看见了一个有趣的问题 为什么医生 律师 教师等传统职业都是越老越吃香 不出意料 这个问题的浏览量非常高 下面回答众说纷纭 但让我印象深刻的还是下面这个回答 犀利而真实 作为声名远扬的高薪职业 程序员相关话题一直是焦点 如 薪资
  • Macos下重置MySQL密码

    环境信息 Macos Catalina 10 15 7 19H2 MySQL 8 0 22 问题 忽然一段时间忘记了MySQL数据库的密码 登录不上去了 该如何办呢 预想中的路径 mysqld safe skip grant tables
  • 转载:电缆种类及选型计算

    电缆种类及选型计算一 电缆的定义及分类 广义的电线电缆亦简称为电缆 狭义的电缆是指绝缘电缆 它可定义为 由下列部分组成的集合体 一根或多根绝缘线芯 以及它们各自可能具有的包覆层 总保护层及外护层 电缆亦可有附加的没有绝缘的导体 我国的电线电
  • dockerfile制作各应用镜像实例

    目标 例如 记录 dockerfile制作各应用镜像实例代码 应用实例 搭建jar应用程序docker容器 Dockerfile文件 FROM java 8 MAINTAINER 126 126 net COPY automation 1
  • NuajWeatherSystem实现昼夜更替

    实现昼夜交替以及纬度变化 还有影响灯光的变化的Unity 3d插件 链接 http pan baidu com s 1mhFZa8w 密码 y3v1
  • gitlab帮助文档

    SSH keys An SSH key allows you to establish 建立 a secure connection between your computer and GitLab Before generating an
  • 项目1——博客系统

    一 绪言 今天又来更新博文了 学习Java也已经有一段时间了 经过这段时间的学习 我对Java有了更深一层的理解 从刚开始的HelloWorld到了现在的小型网页项目 这中间也经历了很多 话不多说 下面开始我的项目阐述 由于是第一次做 必然
  • Java实现对称加密算法-AES加解密

    AES Advanced Encryption Standard 意思是高级加密标准 是一种区块加密标准 这个标准用来替代原先的DES 且已经被广泛使用 DES使用56位密钥 所以比较容易被破解 AES可以使用128 192 和256位密钥