前后端(JAVA)实现AES对称加解密方式

文章目录

  • 前后端(JAVA)实现AES对称加解密方式
    • 1 对称加密分类以及概括
      • 1.1 加密安全等级 DES < 3DES < AES < RC
      • 1.2 DES
      • 1.3 3DES
      • 1.4 AES
      • 1.5 RC
    • 2 前后端实现AES对称加解密方式
    • 3 后端AES对称加解密(ECB和CBC模式)工具类
    • 4 前端(VUE)AES对称加解密(CBC模式)工具类
      • 4.1 aseKeConfig.js AES+CBC配置
      • 4.2 加密解密工具类 aesSecretUtil.js

前后端(JAVA)实现AES对称加解密方式

1 对称加密分类以及概括

文章《加解密篇 - 对称加密算法 (DES、3DES、AES、RC)》有对这几种对称加密的说明,我大概概括一下。

1.1 加密安全等级 DES < 3DES < AES < RC

依次是DES < 3DES < AES < RC

1.2 DES

DES全称 Data Encryption Standard,是一种使用密钥加密的块算法,该加密算法运用非常普遍,是一种标准的加密算法。现在认为是一种不安全的加密算法,因为现在已经有用穷举法攻破 DES 密码的报道了,所以诞生了3DES。

1.3 3DES

3DES(或称为 Triple DES)是三重数据加密算法(TDEA,Triple Data Encryption Algorithm)块密码的通称。它相当于是对每个数据块应用三次 DES 加密算法。

1.4 AES

AES 加密算法的安全性要高于 DES 和 3DES,所以 AES 已经成为了主要的对称加密算法。AES 加密算法就是众多对称加密算法中的一种,它的英文全称是 Advanced Encryption Standard,翻译过来是高级加密标准,它是用来替代之前的 DES 加密算法的。

AES 一共有四种加密模式,分别是 ECB(电子密码本模式)、CBC(密码分组链接模式)、CFB、OFB,我们一般使用的是 CBC 模式。四种模式中除了 ECB 相对不安全之外,其它三种模式的区别并没有那么大。

1.5 RC

RC加密包括RC2,RC4,RC5,RC2 是由著名密码学家 Ron Rivest 设计的一种传统对称分组加密算法,它可作为 DES 算法的建议替代算法。它的输入和输出都是64bit。密钥的长度是从1字节到128字节可变,但目前的实现是8字节(1998年)。

参考:
加解密篇 - 对称加密算法 (DES、3DES、AES、RC)

2 前后端实现AES对称加解密方式

  1. AES为对称加密算法,顾名思义,如果是前后端加解密场景,那前端需要保存一份秘钥,后端也需要保存一份秘钥,这两个秘钥是相同的,才可以实现加解密。

  2. AES的秘钥默认长度为16位,初始向量 IV也是16位,这两个默认长度一定要遵守,否则会有很多不可未知的错误。如果需要增加秘钥的长度增加复杂性,则推荐使用RC加密算法,因为该算法的秘钥长度可变。

  3. 待解密长度需要为16的倍数,否则会报以下错误,常用的解决办法为加密后使用Base64包装密文,则会自动补齐为16的倍数,解密时先使用Base64解密,则密文一定是16的整数倍。

    Input length must be multiple of 16 when decrypting with padded cipher
    

3 后端AES对称加解密(ECB和CBC模式)工具类

import org.apache.commons.lang3.StringUtils;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Base64;/*** @author * @description AES加解密(ECB和CBC模式)* @date 2023/12/8 15:08*/
public class AESEncryptUtil {/*** 加密模式* ECB: AES/ECB/PKCS5Padding* CBC: AES/CBC/NoPadding*/private static final String[] TRANSFORM_ALGORITHM = new String[]{"AES/ECB/PKCS5Padding", "AES/CBC/NoPadding"};/*** 初始向量样式 IV*/private static String iv =  "HBJNRU56MDk4NzK6";private static final String ALGORITHM = "AES";private static final String CHARSET_NAME = "UTF-8";/*** AES加解key样式*/public static String ENCRYPT_KEY = "7CC408B24462ABD1";/*** AES的ECB模式加解* @param data 待加密参数* @param key 加密key* @return*/public static String encryptECB(String data, String key) {if (StringUtils.isEmpty(key)) {throw new IllegalArgumentException("加密失败,加密key为空");}SecretKeySpec aesKey = new SecretKeySpec(key.getBytes(Charset.forName(CHARSET_NAME)), ALGORITHM);try {Cipher cipher = Cipher.getInstance(TRANSFORM_ALGORITHM[0]);cipher.init(Cipher.ENCRYPT_MODE, aesKey);byte[] encrypted = cipher.doFinal(data.getBytes(Charset.forName(CHARSET_NAME)));// 使用Base64来包装是规避报错Input length must be multiple of 16 when decrypting with padded cipher// 解密的字节数组必须是16的倍数return Base64.getEncoder().encodeToString(encrypted);} catch (Exception e) {throw new IllegalArgumentException("加密失败: "+ e.getMessage());}}/*** AES的ECB模式解密* @param data 待解密参数* @param key 解密key* @return*/public static String decryptECB(String data, String key) {if (StringUtils.isEmpty(key)) {throw new IllegalArgumentException("解密失败,解密key为空");}byte[] decode = Base64.getDecoder().decode(data.getBytes(StandardCharsets.UTF_8));SecretKeySpec aesKey = new SecretKeySpec(key.getBytes(Charset.forName(CHARSET_NAME)), ALGORITHM);try {Cipher cipher = Cipher.getInstance(TRANSFORM_ALGORITHM[0]);cipher.init(Cipher.DECRYPT_MODE, aesKey);return new String(cipher.doFinal(decode));} catch (Exception e) {throw new IllegalArgumentException("解密失败: "+ e.getMessage());}}/*** AES的CBC模式加密* @param data 要加密的数据* @param key 加密key* @return 加密的结果*/public static String encryptCBC(String data, String key) {try {// "算法/模式/补码方式"Cipher cipher = Cipher.getInstance(TRANSFORM_ALGORITHM[1]);int blockSize = cipher.getBlockSize();byte[] dataBytes = data.getBytes(StandardCharsets.UTF_8);int plaintextLength = dataBytes.length;if (plaintextLength % blockSize != 0) {plaintextLength = plaintextLength + (blockSize - (plaintextLength % blockSize));}byte[] plaintext = new byte[plaintextLength];System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length);SecretKeySpec keyStr = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES");IvParameterSpec ivStr = new IvParameterSpec(iv.getBytes(StandardCharsets.UTF_8));cipher.init(Cipher.ENCRYPT_MODE, keyStr, ivStr);byte[] encrypted = cipher.doFinal(plaintext);return Base64.getEncoder().encodeToString(encrypted);} catch (Exception e) {throw new IllegalArgumentException("加密失败: "+ e.getMessage());}}/*** AES的CBC模式解密* @param data 要解密的数据* @param key 解密key* @return 解密的结果*/public static String decryptCBC(String data, String key) {try {byte[] encrypted1 = Base64.getDecoder().decode(data);Cipher cipher = Cipher.getInstance(TRANSFORM_ALGORITHM[1]);SecretKeySpec keyStr = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES");IvParameterSpec ivStr = new IvParameterSpec(iv.getBytes(StandardCharsets.UTF_8));cipher.init(Cipher.DECRYPT_MODE, keyStr, ivStr);byte[] original = cipher.doFinal(encrypted1);return new String(original, StandardCharsets.UTF_8);} catch (Exception e) {throw new IllegalArgumentException("解密失败: "+ e.getMessage());}}public static void main(String[] args) throws Exception {String data = "hello Test symmetric encry";String keyStr = "7CC408B24462ABD1";String encryDataStr = encryptECB(data, keyStr);System.out.println("encryptECB = " + encryDataStr);System.out.println("decryptECB = " + decryptECB(encryDataStr, keyStr));encryDataStr = encryptCBC(data, keyStr);System.out.println("encryptCBC = " + encryDataStr);System.out.println("decryptCBC = " + decryptCBC(encryDataStr, keyStr));}}

4 前端(VUE)AES对称加解密(CBC模式)工具类

前端其他工程配置请看文章《java前后端参数和返回加密解密AES+CBC》

npm install crypto-js

4.1 aseKeConfig.js AES+CBC配置

export const AES_KEY = 'MTIzNDU2Nzg5MEFC'
export const AES_IV = 'QUJDRURGMDk4NzY1'
// 参数是否进行加密设置,需要与后端配置保持一致
export const PARAM_ENCRYPT_ABLE = true
// 结果是否进行加密
export const RESULT_ENCRYPT_ABLE = true
// 需要排除的不进行加密的接口,正则匹配
export const EXCLUE_PATH = ['.*/orc/.*', '.*/fastdfs/.*', '.*/eempFastdfs/.*', ',.*/homepage/preview', '.*oauth/getClickApplicationInfo', '.*/common/defaultKaptcha.*', '.*/autoKeyword$', '.*/getLayerCount$', '.*/getLayerInfoListByPage$','.*/epUiImgSaveAndAnalysisMultipartFile$', '/v7/weather']

4.2 加密解密工具类 aesSecretUtil.js

import CryptoJS from 'crypto-js'
import {AES_KEY,AES_IV,PARAM_ENCRYPT_ABLE,EXCLUE_PATH,RESULT_ENCRYPT_ABLE
}
from '../config/aesKeyConfig.js'
const key = CryptoJS.enc.Utf8.parse(AES_KEY) // 16位const iv = CryptoJS.enc.Utf8.parse(AES_IV)const excluePath = EXCLUE_PATHconst paramEncryptAble = PARAM_ENCRYPT_ABLEconst resultEncryptAble = RESULT_ENCRYPT_ABLE/***Description AES CBC BASE64加密解密*@author*@date 13:38 2022/3/31*/export default {// aes加密encrypt(word) {let encrypted = ''if (typeof word === 'string') {const srcs = CryptoJS.enc.Utf8.parse(word)encrypted = CryptoJS.AES.encrypt(srcs, key, {iv: iv,mode: CryptoJS.mode.CBC,padding: CryptoJS.pad.ZeroPadding})} else if (typeof word === 'object') {// 对象格式的转成json字符串const data = JSON.stringify(word)const srcs = CryptoJS.enc.Utf8.parse(data)encrypted = CryptoJS.AES.encrypt(srcs, key, {iv: iv,mode: CryptoJS.mode.CBC,padding: CryptoJS.pad.ZeroPadding})}return CryptoJS.enc.Base64.stringify(encrypted.ciphertext)},// aes解密decrypt(word) {if (word) {let base64 = CryptoJS.enc.Base64.parse(word)let src = CryptoJS.enc.Base64.stringify(base64)var decrypt = CryptoJS.AES.decrypt(src, key, {iv: iv,mode: CryptoJS.mode.CBC,padding: CryptoJS.pad.ZeroPadding})var decryptedStr = decrypt.toString(CryptoJS.enc.Utf8)return decryptedStr.toString()} else {return word}},// 判断url是否在匹配的正则表达式上,匹配则不进行加密,不配则需要加密checkIsExcluePath(url) {// 如果包含需要排除加密的接口返回truelet flag = falsefor (let i = 0; i < excluePath.length; i++) {if (new RegExp('^' + excluePath[i]).test(url)) {flag = truebreak} else {flag = false}}return flag},// 判断是否请求需要进行加密,配置值true的时候需要加密否则不需要checkParamEncryptAble() {// console.log(encryptAble)return paramEncryptAble},// 判断是否只对结果进行加密checkResultEncryptAble() {// console.log(encryptAble)return resultEncryptAble}}

参考:
java前后端参数和返回加密解密
对称加密( 共享密钥密码 ) —用相同的密钥进行加密和解密
手写一个java加密工具类Securit
Java中的AES加解密(CBC模式)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/213438.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Python百宝箱】从传感器到云端:深度解析Python在物联网中的多面应用

迈向智能未来&#xff1a;Python与物联网生态系统的完美融合 前言 随着物联网技术的不断发展&#xff0c;Python作为一种灵活且强大的编程语言&#xff0c;逐渐成为物联网开发的重要工具之一。本文将深入探讨物联网领域中常用的Python库和框架&#xff0c;涵盖了从轻量级通信…

JavaScript <有道翻译之数据解密‘23年12月06日版‘>--案例(三)

前言: 记得上半年还是去年,有道翻译还是直接返回明文数据;现在也跟着,用接口返回加密数据了; 娱乐一下,破他的密文数据... 成品效果图: js部分: 对于找他的密文数据有点费时,针对密文--->搜他地址和启动器不是特别容易,辗转多时(搜:descrypt/json.parse 结合使用更快),有图…

通讯录实现

下方是头文件的代码 #define _CRT_SECURE_NO_WARNINGS #include <assert.h> #include<stdio.h> #include<string.h> #include<stdlib.h>#define NAME_MAX 20 #define SEX_MAX 6 #define TELE_MAX 12 #define ADDR_MAX 30 #define MAX 100 #define D…

swing快速入门(四)

注释很详细&#xff0c;直接上代码 上一篇 增加内容 流式布局范例 import java.awt.*;public class swing_test_2{public static void main(String[] args){//创建一个窗口对象Frame framenew Frame("test");//设置窗口大小frame.setSize(800,800);//这里演示的是…

Gateway全局异常处理及请求响应监控

前言 我们在上一篇文章基于压测进行Feign调优完成的服务间调用的性能调优&#xff0c;此时我们也关注到一个问题&#xff0c;如果我们统一从网关调用服务&#xff0c;但是网关因为某些原因报错或者没有找到服务怎么办呢&#xff1f; 如下所示&#xff0c;笔者通过网关调用acc…

中小企业管理者如何培育团队精神?

某石油工程有限公司总经理曾提问&#xff1a;“作为中小企业的管理者如何才能更好的激发团队精神呢&#xff1f;” 每个企业都向往和号召团队精神&#xff0c;但是往往事与愿违。在各种羡慕嫉妒恨的情绪影响下&#xff0c;难免会产生一些落差&#xff0c;影响到团队精神。 所…

超声波清洗机会损伤物品吗?一文明白超声波清洗机有哪些优点

正确使用超声波清洗机且买对超声波清洗机是不会对清洗物品造成伤害的&#xff01; 一、超声波清洗机工作原理是如何的&#xff1f; 超声波清洗机的工作原理是利用超声波产生的空化振动来清洁物体。当超声波在清洗液中传播时&#xff0c;它会产生微小的气泡和振动&#xff0c;这…

论jenkins的使用方法(初步)

&#x1f4d1;打牌 &#xff1a; da pai ge的个人主页 &#x1f324;️个人专栏 &#xff1a; da pai ge的博客专栏 ☁️宝剑锋从磨砺出&#xff0c;梅花香自苦寒来 目录 &#x1f4d1;什么是持续集成&…

1-1、Java概述

语雀原文链接 文章目录 1、Java发展2、Java体系结构3、Java特点 1、Java发展 1990年&#xff0c;Sun公司(Stanford University Network,斯坦福大学网络公司)詹姆斯高斯林推出的一门语言最开始注册的名字oak语言(橡树)&#xff0c;重名了被迫改成Java2009年Sun公司被甲骨文Ora…

Docker 容器中使用 Docker - DinD 和 DooD

突然间研究这个来的缘由是正在从 Jenkins 往 Harness 的过度, 而完全用命令来构建 Docker 镜像变得不一样了。在 Jenkins 中 Agent 本身也是一个 Docker Daemon, 所以 Docker 命令执行无障碍&#xff0c;而 Harness 的所谓的 Agent 就是一个个的运行在 Kubernetes 中的 Docker …

error:gmapping

– Could not find the required component ‘gmapping’. The following CMake error indicates that you either need to install the package with the same name or change your environment so that it can be found. CMake Error at /opt/ros/kinetic/share/catkin/cmake…

logstash插件简单介绍

logstash插件 输入插件(input) Input&#xff1a;输入插件。 Input plugins | Logstash Reference [8.11] | Elastic 所有输入插件都支持的配置选项 SettingInput typeRequiredDefaultDescriptionadd_fieldhashNo{}添加一个字段到一个事件codeccodecNoplain用于输入数据的…

【SpringBoot教程】SpringBoot Thymeleaf 基于HTML5的现代模板引擎

作者简介&#xff1a;大家好&#xff0c;我是撸代码的羊驼&#xff0c;前阿里巴巴架构师&#xff0c;现某互联网公司CTO 联系v&#xff1a;sulny_ann&#xff08;17362204968&#xff09;&#xff0c;加我进群&#xff0c;大家一起学习&#xff0c;一起进步&#xff0c;一起对抗…

error:move_base_msgs

CMake Warning at /opt/ros/kinetic/share/catkin/cmake/catkinConfig.cmake:76 (find_package): Could not find a package configuration file provided by “move_base_msgs” with any of the following names: move_base_msgsConfig.cmake move_base_msgs-config.cmake …

鼠标光标不见了怎么办?速速get这4个方法!

“非常奇怪&#xff0c;我的鼠标光标用着用着就不见了&#xff0c;这是为什么呢&#xff1f;有什么方法可以解决这个问题吗&#xff1f;” 在电脑使用过程中&#xff0c;有时候会遇到鼠标光标突然消失的情况&#xff0c;这无疑会给我们日常操作带来很大的不便。那么&#xff0c…

Linux bin包生成

需求背景&#xff1a; 在实际项目时我们很少把源码用个tar给到客户&#xff0c;这样显得很不专业&#xff0c;且有的时候我们提供补丁&#xff0c;那么这个时候我们提供一个补丁的bin包可以直接安装运行就显得很高大上了。 物料准备 准备一台liunx&#xff0c;虚拟机亦可&am…

自定义插件vue-router简单实现hashRouter设计思路

步骤 1.挂载 vue.prototype.$router 2.声明两个组件 router-view this.$router.current>component > h(component) router-link h(a,{attrs:{href:#this.to}},this.$slots.default) 3.url的监听&#xff1a;window hashchange的改变 4.定义响应式current&#xff0…

使用Python提取PDF文件中指定页面的内容

在日常工作和学习中&#xff0c;我们经常需要从PDF文件中提取特定页面的内容。在本篇文章中&#xff0c;我们将介绍如何使用Python编程语言和两个强大的库——pymupdf和wxPython&#xff0c;来实现这个任务。 1. 准备工作 首先&#xff0c;确保你已经安装了以下两个Python库&…

JavaScript深拷贝和浅拷贝

对于原始数据类型&#xff0c;并没有深浅拷贝的区别&#xff0c;深浅拷贝都是对于引用数据类型而言&#xff0c;如果我们要赋值对象的所有属性都是引用类型可以用浅拷贝 浅拷贝&#xff1a;只复制一层对象&#xff0c;当对象的属性是引用类型时&#xff0c;实质复制的是其引用&…

【办公软件】Outlook启动一直显示“正在启动”的解决方法

早上打开电脑Outlook2016以后&#xff0c;半个多小时了&#xff0c;一直显示这个界面&#xff1a; 解决办法 按WIN R键打开“运行”&#xff0c;输入如下命令&#xff1a; outlook.exe /safe 然后点击“确定” 这样就进入了Outlook的安全模式。 点击“文件”->“选项”-…