当前位置: 首页 > news >正文

Java 最简单的实现 AES 加密和解密

AES简介

AES(Advanced Encryption Standard)高级加密标准,是一种被广泛使用的对称加密算法,用于加密和解密数据。它曾经是美国政府的一个机密标准,但现在已成为公开的加密算法,并被广泛使用于商业、政府及军事领域。

AES算法有三种不同的密钥长度:128位、192位和256位,每种长度有不同数量的轮数,其中128位密钥需要进行10轮加密,192位密钥需要进行12轮加密,256位密钥需要进行14轮加密。其中,轮数指的是加密算法中处理数据的重复次数,每轮中会对数据进行代换、置换、线性变换等操作,以增强加密强度。

AES算法的加密和解密过程使用的是相同的密钥,因此被称为对称密钥加密算法。它通过将明文按照固定大小分块(128比特),并对每个块进行相同的加密操作,从而实现加密。解密时则对密文进行反向操作即可。

总体来说,AES算法具有安全、高效等优势,已成为目前最常用的加密算法之一。

一、示例

1.加密解密工具类

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;/*** @author rwy* @Title:* @Package* @Description:* @date 2023-11-22 15:37*/
@Component
public class AESEncryption {//十六位十六进制数作为秘钥(下面有提供随机生成密钥)private static final String SECRET_KEY = "mySecretKey123456";//十六位十六进制数作为秘钥偏移量(可以和前端自行商量)private static final String INIT_VECTOR = "myInitializationVector";/*** AES加密* @param originalString* @return* @throws Exception*/public static String encrypt(String originalString) throws Exception {Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");SecretKeySpec secretKeySpec = new SecretKeySpec(SECRET_KEY.getBytes(), "AES");IvParameterSpec ivParameterSpec = new IvParameterSpec(INIT_VECTOR.getBytes());cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);byte[] encryptedBytes = cipher.doFinal(originalString.getBytes());return Base64.getEncoder().encodeToString(encryptedBytes);}/*** AES解密* @param encryptedString* @return* @throws Exception*/public static String decrypt(String encryptedString) throws Exception {Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");SecretKeySpec secretKeySpec = new SecretKeySpec(SECRET_KEY.getBytes(), "AES");IvParameterSpec ivParameterSpec = new IvParameterSpec(INIT_VECTOR.getBytes());cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedString));return new String(decryptedBytes);}public static void main(String[] args) {try {String originalString = "Hello, World!";String encryptedString = encrypt(originalString);System.out.println("Encrypted: " + encryptedString);String decryptedString = decrypt(encryptedString);System.out.println("Decrypted: " + decryptedString);} catch (Exception e) {e.printStackTrace();}}
}

2.AES随机生成密钥

public static void main(String[] args) {try {KeyGenerator kg = KeyGenerator.getInstance("AES");kg.init(128);//要生成多少位,只需要修改这里即可128, 192或256SecretKey sk = kg.generateKey();byte[] b = sk.getEncoded();String s = byteToHexString(b);System.out.println(s);System.out.println("十六进制密钥长度为"+s.length());System.out.println("二进制密钥的长度为"+s.length()*4);}catch (NoSuchAlgorithmException e) {e.printStackTrace();System.out.println("没有此算法。");}}public static String byteToHexString(byte[] bytes) {StringBuffer sb = new StringBuffer();for (int i = 0; i < bytes.length; i++) {String strHex=Integer.toHexString(bytes[i]);if(strHex.length() > 3) {sb.append(strHex.substring(6));} else {if(strHex.length() < 2) {sb.append("0" + strHex);} else {sb.append(strHex);}}}return sb.toString();}

二、登录实战完整代码

1.前端:

这里前端传过来的密码是加密过后

前端加密解密可参考:

vue MD5加密和AES加密方法_vue 加密_IDycy的博客-CSDN博客

2.后端

/*** 账号密码登录* @param user* @return* @throws Exception*/
@PostMapping("/cs")public Result<JSONObject> login(@RequestBody SysUser user) throws Exception {Result<JSONObject> result = new Result<JSONObject>();LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(SysUser::getUsername, user.getUsername());SysUser sysUser = sysUserService.getOne(queryWrapper);result = sysUserService.checkUserIsEffective(sysUser);if (!result.isSuccess()) {return result;}//1. 解密前端传过来的加密的密码String decryptAse = aesEncryption(user.getPassword());//2. 校验用户名或密码是否正确String userpassword = PasswordUtil.encrypt(user.getUsername(), decryptAse, sysUser.getSalt());String syspassword = sysUser.getPassword();if (!syspassword.equals(userpassword)) {result.error500("用户名或密码错误");return result;}//以下代码忽略...return result;}

相关文章:

  • Spring-IOC-FactoryBean机制(难点且重点)
  • Java面试题07
  • 重磅!TikTok Shop将以新方式重启印尼业务
  • 前端学习--React(1)
  • 小红书干货类笔记怎么写?建议收藏
  • Maven聚合项目发布至私服指定模块
  • 设计模式(二)-创建者模式(3)-抽象工厂模式
  • 使用Python解析CAN总线
  • 【华为OD题库-030】阿里巴巴找黄金宝箱(V)-java
  • 2023-浅谈模型
  • 前端面试算法之“时间复杂度
  • Qt 基于海康相机的视频绘图
  • NX二次开发UF_CAM_reinit_session 函数介绍
  • android报错
  • druid keepAlive 导致数据库连接数飙升
  • Java 23种设计模式 之单例模式 7种实现方式
  • jdbc就是这么简单
  • mysql外键的使用
  • Netty 框架总结「ChannelHandler 及 EventLoop」
  • niucms就是以城市为分割单位,在上面 小区/乡村/同城论坛+58+团购
  • oldjun 检测网站的经验
  • React Transition Group -- Transition 组件
  • React系列之 Redux 架构模式
  • SpiderData 2019年2月25日 DApp数据排行榜
  • Spring框架之我见(三)——IOC、AOP
  • vue:响应原理
  • 问题之ssh中Host key verification failed的解决
  • 原生js练习题---第五课
  • 正则表达式小结
  • 最近的计划
  • ​无人机石油管道巡检方案新亮点:灵活准确又高效
  • !! 2.对十份论文和报告中的关于OpenCV和Android NDK开发的总结
  • #100天计划# 2013年9月29日
  • (3)(3.2) MAVLink2数据包签名(安全)
  • (libusb) usb口自动刷新
  • (二)正点原子I.MX6ULL u-boot移植
  • (附源码)spring boot校园健康监测管理系统 毕业设计 151047
  • (附源码)流浪动物保护平台的设计与实现 毕业设计 161154
  • (六)激光线扫描-三维重建
  • (三)centos7案例实战—vmware虚拟机硬盘挂载与卸载
  • (转)详解PHP处理密码的几种方式
  • *++p:p先自+,然后*p,最终为3 ++*p:先*p,即arr[0]=1,然后再++,最终为2 *p++:值为arr[0],即1,该语句执行完毕后,p指向arr[1]
  • .NET Standard、.NET Framework 、.NET Core三者的关系与区别?
  • .NET 的静态构造函数是否线程安全?答案是肯定的!
  • .net和php怎么连接,php和apache之间如何连接
  • .NET与 java通用的3DES加密解密方法
  • @Not - Empty-Null-Blank
  • [ C++ ] STL---仿函数与priority_queue
  • [Android学习笔记]ScrollView的使用
  • [C#]OpenCvSharp结合yolov8-face实现L2CS-Net眼睛注视方向估计或者人脸朝向估计
  • [CUDA手搓]从零开始用C++ CUDA搭建一个卷积神经网络(LeNet),了解神经网络各个层背后算法原理
  • [C语言][PTA基础C基础题目集] strtok 函数的理解与应用
  • [docker] Docker的数据卷、数据卷容器,容器互联
  • [Flutter]打包IPA
  • [HTML]Web前端开发技术18(HTML5、CSS3、JavaScript )HTML5 基础与CSS3 应用——喵喵画网页