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

AES加密中的CBC和ECB

目录

1.说明

2.ECB模式(base64)

3.CBC模式

4.总结


1.说明

AES是常见的对称加密算法,加密和解密使用相同的密钥,流程如下:

主要概念如下:

①明文

②密钥

用来加密明文的密码,在对称加密算法中,加密与解密的密钥是相同的。密钥为接收方与发送方协商产生,但不可以直接在网络上传输,否则会导致密钥泄漏,通常是通过加密算法(如非对称加密或者md5加密等)加密密钥,然后再通过网络传输给对方,或者直接面对面商量密钥。密钥是绝对不可以泄漏的,否则会被攻击者还原密文,窃取机密数据。

③加密函数

将明文,密钥及IV变量作为参数,生成加密后的密文,有的加密模式没有IV变量

④解密函数

将密文,密钥及IV变量作为参数,生成解密后的明文,有的加密模式没有IV变量

⑤密文

2.加密的组成部分

①密钥(有长度限制)

分为AES128,AES192,AES256。

AES128:要求密钥长度为16个字节,分为四行四列的矩阵。

AES192:要求密钥长度为24个字节,分为四行六列的矩阵。

AES256:要求密钥长度为32个字节,分为四行八列的矩阵。

②加密模式

ECB,CBC,CFB,OFB,CTR,CCM,GCM,XTS

③填充模式

 AES加密是以16个字节为一组进行分组加密,要求明文的长度一定是16个字节的整数倍,如果不够16个字节的倍数,需要按照填充模式进行填充。填充模式如下:

NONE:不填充,要求明文长度必须是16个字节的整数倍。

PKCS7:缺多少就补充多少个字节数量。

ZERO:缺多少就补充多少个字节的0。

ANSI923:最后一个字节填充缺少的数量,其他字节填充0。

ISO7816_4:填充的第一个字节为16进制的0x80,其他字节填充0。

ISO10126:最后一个字节填充缺少的数量,其他字节填充随机数。

注意:当明文长度已经是16个字节的整数倍时,当填充模式为NONE以外的模式时,也会进行填充,填充16个16。

2.ECB模式(base64)

加密执行流程:

(1)前端加密及解密

①引入依赖

npm install crypto-js 

②加密及解密的工具类

import CryptoJS from 'crypto-js'// ECB模式
export function Encrypt(word,key) {let srcs = CryptoJS.enc.Utf8.parse(word);let keyInfo = CryptoJS.enc.Utf8.parse(key);let encrypted = CryptoJS.AES.encrypt(srcs, keyInfo, {mode: CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7})
//返回base64格式的加密结果return CryptoJS.enc.Base64.stringify(encrypted.ciphertext);
}export function Decrypt(word,key) {let keyInfo = CryptoJS.enc.Utf8.parse(key);let base64 = CryptoJS.enc.Base64.parse(word);let srcs = CryptoJS.enc.Base64.stringify(base64);const decrypt = CryptoJS.AES.decrypt(srcs, keyInfo, {mode: CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7});const decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);return decryptedStr;
}

前端填充方式:

        /*** Padding namespace.*/export namespace pad {/*** PKCS #5/7 padding strategy.*/const Pkcs7: Padding;/*** ANSI X.923 padding strategy.*/const AnsiX923: Padding;/*** ISO 10126 padding strategy.*/const Iso10126: Padding;/*** ISO/IEC 9797-1 Padding Method 2.*/const Iso97971: Padding;/*** Zero padding strategy.*/const ZeroPadding: Padding;/*** A noop padding strategy.*/const NoPadding: Padding;}

(2)后端加密及解密

①引入依赖

        <dependency><groupId>commons-codec</groupId><artifactId>commons-codec</artifactId><version>1.14</version></dependency>

②后端加密及解密工具类

package com.example.utils;import org.apache.commons.codec.binary.Base64;import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;/*** ECB加解密工具类*/
public class AesTool {private static String ALGO = "AES";private static byte[] keyValue = "TD2g45EfXqGnBLaXpzPZ6A==".getBytes();/*** <p>description: 加密</p >* <p>param: [Data] </p >* <p>return: java.lang.String </p >* <p>author: zhangcj </p >* <p>date: 2021/12/29 </p >*/public static String encrypt(String data) {try {Key key = generateKey();Cipher c = Cipher.getInstance(ALGO);c.init(1, key);byte[] encVal = c.doFinal(data.getBytes());String encryptedValue = Base64.encodeBase64String(encVal);return encryptedValue;} catch (Exception var5) {throw new RuntimeException(var5);}}// public static String decrypt(String encryptedData, String keyValue) {//     try {//         Key key = generateKey(keyValue);//         Cipher c = Cipher.getInstance(ALGO);//         c.init(2, key);//         byte[] decordedValue = Base64.decodeBase64(encryptedData);//         byte[] decValue = c.doFinal(decordedValue);//         String decryptedValue = new String(decValue);//         return decryptedValue;//     } catch (Exception var6) {//         throw new RuntimeException(var6);//     }// }public static String decrypt(String content,String password) throws Exception {byte[] contentNew = Base64.decodeBase64(content);SecretKeySpec skeySpec = new SecretKeySpec(password.getBytes("UTF-8"), "AES");Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); // "算法/模式/补码方式"cipher.init(Cipher.DECRYPT_MODE, skeySpec);return new String(cipher.doFinal(contentNew));}private static Key generateKey() throws Exception {Key key = new SecretKeySpec(keyValue, ALGO);return key;}private static Key generateKey(String key) throws Exception {return new SecretKeySpec(key.getBytes(), ALGO);}
}

③调用方式

        String decrypt = AesTool.decrypt("D5DT/9wwi89s0ny9VYwMTA==", "5bzMeuzs2XQfG8QFyx1hGg==");System.out.println(decrypt);

(3)说明

①密钥长度必须是16个字节,24个字节或者32个字节,如果不是,可以进行加密,但是不能进行解密。

②ECB模式加密,将明文及密钥通过CryptoJS.enc.Utf8.parse进行转换,将UTF8编码的字符串转换为字节数组,然后加密模式及填充方式,最后生成密文。

③密文分为两种格式,一种是base64,另一种是hex。

④前端加密之后,后端进行解密时,首先根据前端的密文格式,将密文转换成字节数组,再设置和前端一致的模式和补充方式进行解密。

⑤ECB模式加密安全性较低,但性能很高,相同的明文段加密后的密文一致。

⑥前端加密需要的密钥可以由后端生成,生成方式如下:

        // 方式1KeyGenerator keyGen = KeyGenerator.getInstance("AES");keyGen.init(128);SecretKey secretKey = keyGen.generateKey();byte[] keyBytes = secretKey.getEncoded();String key = Base64.getEncoder().encodeToString(keyBytes);System.out.println(key);// 方式2SecureRandom secureRandom = new SecureRandom();KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");keyGenerator.init(128, secureRandom);byte[] key2 = keyGenerator.generateKey().getEncoded();String base64Key = java.util.Base64.getEncoder().encodeToString(key2);System.out.println(base64Key);

主要分为两步:生成一个随机的AES密钥;将密钥已base64编码的形式保存或传输。

3.CBC模式

(1)前端加密及解密

①引入依赖

npm install crypto-js 

②加密及解密工具类

import CryptoJS from 'crypto-js'// CBC模式
export function Encrypt1(word,key,iv) {let srcs = CryptoJS.enc.Utf8.parse(word);let keyInfo = CryptoJS.enc.Utf8.parse(key);let ivInfo = CryptoJS.enc.Utf8.parse(iv);let encrypted = CryptoJS.AES.encrypt(srcs, keyInfo, {iv: ivInfo ,mode: CryptoJS.mode.CBC,padding: CryptoJS.pad.Pkcs7})return CryptoJS.enc.Base64.stringify(encrypted.ciphertext);
}
export function Decrypt1(word,key,iv) {let keyInfo = CryptoJS.enc.Utf8.parse(key);let ivInfo = CryptoJS.enc.Utf8.parse(iv);let base64  = CryptoJS.enc.Base64.parse(word);let srcs = CryptoJS.enc.Base64.stringify(base64);const decrypt = CryptoJS.AES.decrypt(srcs, keyInfo, {iv: ivInfo ,mode: CryptoJS.mode.CBC,padding: CryptoJS.pad.Pkcs7});const decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);return decryptedStr;
}

 (2)后端加密及解密

①引入依赖

        <dependency><groupId>commons-codec</groupId><artifactId>commons-codec</artifactId><version>1.14</version></dependency>

②加密及解密工具类

package com.example.utils;import org.apache.commons.codec.binary.Base64;import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;/*** @Author linaibo* @Date 2024/2/7 15:53* CBC加解密工具* @Version 1.0*/public class AexCbcTool {// public static String decryptAES(String content,String key, String ivInfo) throws Exception {//     SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("ASCII"), "AES");//     Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");//     IvParameterSpec iv = new IvParameterSpec(ivInfo.getBytes());//     cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);//     byte[] encrypted1 = Base64.decodeBase64(content);//先用bAES64解密//     return new String(cipher.doFinal(encrypted1));// }/*** 解密** @param enc       加密内容* @param uniqueKey 唯一key* @return*/public static String decrypt(String enc, String uniqueKey, String iv) throws Exception {byte[] key = uniqueKey.getBytes();SecretKey secretKey = new SecretKeySpec(key, "AES");IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes("utf-8"));Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec);byte[] encrypted1 = Base64.decodeBase64(enc);//先用bAES64解密byte[] plainBytes = cipher.doFinal(encrypted1);return new String(plainBytes, "UTF-8");}/*** 加密** @param src* @param uniqueKey* @return*/public static String encrypt(String src, String uniqueKey, String iv) throws Exception {byte[] key = uniqueKey.getBytes();SecretKey secretKey = new SecretKeySpec(key, "AES");IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes("utf-8"));Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec);byte[] cipherBytes = cipher.doFinal(src.getBytes("UTF-8"));String encryptedValue = Base64.encodeBase64String(cipherBytes);return encryptedValue;}}

(3)说明

①CBC模式在EBC模式的基础上,追加了iv偏移量的设置。

4.总结

在项目中使用时,比如对密码的加密,需要先调用后端接口获取加密密钥,根据获取的加密密钥在前端对密码进行加密,将加密后的信息发送给后端,在后端进行解密,解密之后再进行加密,将加密后的密码和表中的密码进行比较,一致则登录成功

https://blog.51cto.com/u_16175526/7323980

AES算法的CBC和ECB两种工作模式_aes iv需要保密吗-CSDN博客

AES加解密模式_aes_cbc_encrypt-CSDN博客

AES解密报错Invalid AES key length: xx bytes与Given final block not properly padded的解决方法-CSDN博客

相关文章:

AES加密中的CBC和ECB

目录 1.说明 2.ECB模式&#xff08;base64&#xff09; 3.CBC模式 4.总结 1.说明 AES是常见的对称加密算法&#xff0c;加密和解密使用相同的密钥&#xff0c;流程如下&#xff1a; 主要概念如下&#xff1a; ①明文 ②密钥 用来加密明文的密码&#xff0c;在对称加密算…...

【C++】类和对象(四)

前言&#xff1a;在类和对象中&#xff0c;我们走过了十分漫长的道路&#xff0c;今天我们将进一步学习类和对象&#xff0c;类和对象这块荆棘地很长&#xff0c;各位一起加油呀。 &#x1f496; 博主CSDN主页:卫卫卫的个人主页 &#x1f49e; &#x1f449; 专栏分类:高质量&a…...

XGB-5: DART Booster

XGBoost 主要结合了大量的回归树和一个小的学习率。在这种情况下&#xff0c;早期添加的树是重要的&#xff0c;而晚期添加的树是不重要的。 Vinayak 和 Gilad-Bachrach 提出了一种将深度神经网络社区的 dropout 技术应用于梯度提升树的新方法&#xff0c;并在某些情况下报告了…...

HiveSQL——不使用union all的情况下进行列转行

参考文章&#xff1a; HiveSql一天一个小技巧&#xff1a;如何不使用union all 进行列转行_不 union all-CSDN博客文章浏览阅读881次&#xff0c;点赞5次&#xff0c;收藏10次。本文给出一种不使用传统UNION ALL方法进行 行转列的方法,其中方法一采用了concat_wsposexplode()方…...

Python环境下基于指数退化模型和LSTM自编码器的轴承剩余寿命预测

滚动轴承是机械设备中关键的零部件之一&#xff0c;其可靠性直接影响了设备的性能&#xff0c;所以对滚动轴承的剩余使用寿命(RUL)进行预测是十分必要的。目前&#xff0c;如何准确地对滚动轴承剩余使用寿命进行预测&#xff0c;仍是一个具有挑战的课题。对滚动轴承剩余寿命评估…...

无人机竞赛视觉算法开发流程开源计划(询问大家意见)

本科中参加过一系列的无人机机器人竞赛&#xff0c;像电赛、工训赛、机器人大赛这些&#xff0c;有一些比较常用的方案打算开源一下。现在读研了&#xff0c;也算是对本科的一个总结&#xff0c;但是还是想看看大家意见&#xff0c;大家有什么需求可以在评论区说&#xff0c;我…...

DMA直接内存访问,STM32实现高速数据传输使用配置

1、DMA运用场景 随着智能化、信息化的不断推进&#xff0c;嵌入式设备的数据处理量也呈现指数级增加&#xff0c;因此对于巨大的数据量处理的情况时&#xff0c;必须采取其它的方式去替CPU减负&#xff0c;以保证嵌入式设备性能。例如SD卡存储器和音视频、网络高速通信等其它情…...

Web安全研究(六)

文章目录 HideNoSeek: Camouflaging(隐藏) Malicious JavaScript in Benign ASTs文章结构Introjs obfuscationmethodologyExample HideNoSeek: Camouflaging(隐藏) Malicious JavaScript in Benign ASTs CCS 2019 CISPA 恶意软件领域&#xff0c;基于学习的系统已经非常流行&am…...

python3 中try 异常调试 raise 异常抛出

一、什么是异常&#xff1f; 异常即是一个事件&#xff0c;该事件会在程序执行过程中发生&#xff0c;影响了程序的正常执行。 一般情况下&#xff0c;在Python无法正常处理程序时就会发生一个异常。 异常是Python对象&#xff0c;表示一个错误。 当Python脚本发生异常时我…...

Java中的序列化是什么?如何实现对象的序列化和反序列化?请解释Serializable接口的作用是什么?请解释transient关键字的作用是什么?为什么会使用它?

Java中的序列化是指将对象转换为字节序列的过程&#xff0c;以便可以在网络上传输或将其保存到持久存储介质中。反序列化则是将字节序列重新转换回对象的过程。Java提供了一种称为序列化&#xff08;Serialization&#xff09;的机制来实现对象的序列化和反序列化。 要实现对象…...

二维差分---三维差分算法笔记

文章目录 一.二维差分构造差分二维数组二维差分算法状态dp求b[i][j]数组的二维前缀和图解 二.三维前缀和与差分三维前缀和图解:三维差分核心公式图解:模板题 一.二维差分 给定一个原二维数组a[i][j],若要给a[i][j]中以(x1,y1)和(x2,y2)为对角线的子矩阵中每个数都加上一个常数…...

D. Divisible Pairs

思路&#xff1a;我们预处理出每个数分别摸上xy的值&#xff0c;用map存一下&#xff0c;然后遍历每个数&#xff0c;如果a b是x的倍数的话&#xff0c;那么他们模x的值相加为x&#xff0c;如果a - b是y的倍数的话&#xff0c;那么他们的模y的值相等。 代码&#xff1a; voi…...

【教程】Kotlin语言学习笔记(二)——数据类型(持续更新)

写在前面&#xff1a; 如果文章对你有帮助&#xff0c;记得点赞关注加收藏一波&#xff0c;利于以后需要的时候复习&#xff0c;多谢支持&#xff01; 【Kotlin语言学习】系列文章 第一章 《认识Kotlin》 第二章 《数据类型》 文章目录 【Kotlin语言学习】系列文章一、基本数据…...

react 插槽

问题开发当中会经常出现组件十分相似的组件&#xff0c;只有一部分是不同的 解决&#xff1a; 父组件:在引用的时候 import { Component } from "react"; import Me from "../me";const name <div>名称</div> class Shoop extends Compone…...

Linux运用fork函数创建进程

fork函数&#xff1a; 函数原型&#xff1a; pid_t fork(void); 父进程调用fork函数创建一个子进程&#xff0c;子进程的用户区父进程的用户区完全一样&#xff0c;但是内核区不完全一样&#xff1b;如父进程的PID和子进程的PID不一样。 返回值&#xff1a; RETURN VALUEO…...

Pytest测试技巧之Fixture:模块化管理测试数据

在 Pytest 测试中&#xff0c;有效管理测试数据是提高测试质量和可维护性的关键。本文将深入探讨 Pytest 中的 Fixture&#xff0c;特别是如何利用 Fixture 实现测试数据的模块化管理&#xff0c;以提高测试用例的清晰度和可复用性。 什么是Fixture&#xff1f; 在 Pytest 中&a…...

设计模式-职责链模式Chain of Responsibility

职责链模式 一、原理和实现二、实现方式1) 使用链表实现2) 使用数组实现3) 扩展 作用&#xff1a;复用和扩展&#xff0c;在实际的项目开发中比较常用。在框架开发中&#xff0c;我们也可以利用它们来提供框架的扩展点&#xff0c;能够让框架的使用者在不修改框架源码的情况下&…...

书生浦语大模型实战营-课程作业(3)

下载sentence_transformer的代码运行情况。sentence_transformer用于embedding&#xff08;转向量&#xff09; 本地构建持久化向量数据库。就是把txt和md文件抽取出纯文本&#xff0c;分割成定长&#xff08;500&#xff09;后转换成向量&#xff0c;保存到本地&#xff0c;称…...

考研英语单词25

Day 25 bench n.长凳 elastic n.橡皮圈&#xff0c;松紧带 a.灵活的 “e-last 延伸出去” disaster n.灾难&#xff0c;灾祸【disastrous a.灾难性的&#xff0c;极坏的】 deadly a.致命的&#xff0c;极端的&#xff0c;势不两立的 hike n.徒步旅行&…...

计算机网络——08应用层原理

应用层原理 创建一个新的网络 编程 在不同的端系统上运行通过网络基础设施提供的服务&#xff0c;应用进程批次通信如Web Web服务器软件与浏览器软件通信 网络核心中没有应用层软件 网络核心没有应用层功能网络应用只能在端系统上存在 快速网络应用开发和部署 网络应用…...

Android Wi-Fi 连接失败日志分析

1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分&#xff1a; 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析&#xff1a; CTR…...

C++_核心编程_多态案例二-制作饮品

#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为&#xff1a;煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例&#xff0c;提供抽象制作饮品基类&#xff0c;提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》

引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

【位运算】消失的两个数字(hard)

消失的两个数字&#xff08;hard&#xff09; 题⽬描述&#xff1a;解法&#xff08;位运算&#xff09;&#xff1a;Java 算法代码&#xff1a;更简便代码 题⽬链接&#xff1a;⾯试题 17.19. 消失的两个数字 题⽬描述&#xff1a; 给定⼀个数组&#xff0c;包含从 1 到 N 所有…...

生成 Git SSH 证书

&#x1f511; 1. ​​生成 SSH 密钥对​​ 在终端&#xff08;Windows 使用 Git Bash&#xff0c;Mac/Linux 使用 Terminal&#xff09;执行命令&#xff1a; ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" ​​参数说明​​&#xff1a; -t rsa&#x…...

Spring Boot面试题精选汇总

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序

一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...

LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》

这段 Python 代码是一个完整的 知识库数据库操作模块&#xff0c;用于对本地知识库系统中的知识库进行增删改查&#xff08;CRUD&#xff09;操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 &#x1f4d8; 一、整体功能概述 该模块…...

虚拟电厂发展三大趋势:市场化、技术主导、车网互联

市场化&#xff1a;从政策驱动到多元盈利 政策全面赋能 2025年4月&#xff0c;国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》&#xff0c;首次明确虚拟电厂为“独立市场主体”&#xff0c;提出硬性目标&#xff1a;2027年全国调节能力≥2000万千瓦&#xff0…...

STM32---外部32.768K晶振(LSE)无法起振问题

晶振是否起振主要就检查两个1、晶振与MCU是否兼容&#xff1b;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容&#xff08;CL&#xff09;与匹配电容&#xff08;CL1、CL2&#xff09;的关系 2. 如何选择 CL1 和 CL…...