AES加密中的CBC和ECB

news2024/11/17 8:52:50

目录

1.说明

2.ECB模式(base64)

3.CBC模式


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;
}

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

前端填充方式:

        /**
         * 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)说明

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

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

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

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

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

        // 方式1
        KeyGenerator 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);
        // 方式2
        SecureRandom 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;
    }

}

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博客

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

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

相关文章

【网站项目】032汽车客运站管理系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

ChatGLM3-6B的本地api调用

ChatGLM3-6B的本地api调用方式 1.运行openai_api_demo路径下的openai_api.py 启动后界面&#xff1a; 注意&#xff1a;本地api调到的前提是——本地部署了ChatGLM3-6B,本地部署的教程可参考&#xff1a; 20分钟部署ChatGLM3-6B 部署了若CUDA可用&#xff0c;默认会以CUDA方…

Kubernetes实战(二十六)-K8S 部署Dashboard UI

Kubernetes Dashboard是Kubernetes集群的通用、基于Web的UI。它允许用户管理集群中运行的应用程序并对其进行故障排除&#xff0c;以及管理集群本身。 访问到DashBoard有两种方式&#xff1a; 通过KubernetesAPI访问&#xff1a;Dashboard是Kubernetes的内置的UI插件&#xff…

第8章 智能租房——列表页

学习目标 掌握搜索房源列表页展示功能的逻辑&#xff0c;能够实现在列表中展示符合搜索条件的房源数据 掌握最新房源列表页展示功能的逻辑&#xff0c;能够运用分页插件以分页形式展示最新房源数据 掌握热点房源列表页展示功能的逻辑&#xff0c;能够运用分页插件以分页形式展…

《CSS 简易速速上手小册》第7章:CSS 预处理器与框架(2024 最新版)

文章目录 7.1 Sass&#xff1a;更高效的 CSS 编写7.1.1 基础知识7.1.2 重点案例&#xff1a;主题颜色和字体管理7.1.3 拓展案例 1&#xff1a;响应式辅助类7.1.4 拓展案例 2&#xff1a;深色模式支持 7.2 Bootstrap&#xff1a;快速原型设计和开发7.2.1 基础知识7.2.2 重点案例…

visual studio和cmake如何编译dlib库

官网 dlib C Library 对应的是最新版本&#xff0c;只能用到vs2015版本及以后 如果使用vs2013&#xff0c;所以需要下载vs2013可用的版本。 就是说dlib版本与vs版本有对应关系 所有版本 dlib C Library - Browse /dlib at SourceForge.net Releases davisking/dlib GitHu…

Trie 字典树的两种实现方式

Trie&#xff0c;又称字典树、单词查找树或键树&#xff0c;是一种树形结构&#xff0c;是一种哈希树的变种。典型应用是用于统计&#xff0c;排序和保存大量的字符串&#xff08;但不仅限于字符串&#xff09;&#xff0c;所以经常被搜索引擎系统用于文本词频统计。它的优点是…

Leetcode2560. 打家劫舍 IV

Every day a Leetcode 题目来源&#xff1a;2560. 打家劫舍 IV 解法1&#xff1a;二分答案 动态规划 给定数组 nums&#xff0c;从中选择一个长度至少为 k 的子序列 A&#xff0c;要求 A 中没有任何元素在 nums 中是相邻的。 最小化 max⁡(A)。 看到「最大化最小值」或者…

【Python 千题 —— 基础篇】查找年龄

Python 千题持续更新中 …… 脑图地址 👉:⭐https://twilight-fanyi.gitee.io/mind-map/Python千题.html⭐ 题目描述 题目描述 班级中有 Tom、Alan、Bob、Candy、Sandy 五个人,他们组成字典 {Tom: 23, Alan: 24, Bob: 21, Candy: 22, Sandy: 21},字典的键是姓名,字典的…

实现自定义标记

实现自定义标记 问题陈述 New Tech Book的高级管理层决定在其用JSP设计的应用程序的所有页面上显示版权信息。它们还要去如何向应用程序中添加JSP页面,可以重用显示版本信息的代码。公司的软件开发人员Jerry Smith决定用自定义标记来创建应用程序的这一部分。 解决方案 要解…

上位机图像处理和嵌入式模块部署(利用python开发软件)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 开发windows和linux软件的时候&#xff0c;大家一般都是习惯于用c/c语言进行开发&#xff0c;但是目前来说很多的开发板都是支持python语言开发的。…

Open CASCADE学习|扫掠

目录 1、BRepPrimAPI_MakePrism Draw Test Harness&#xff1a; C&#xff1a; 2、BRepPrimAPI_MakeRevol Draw Test Harness&#xff1a; C&#xff1a; 3、BRepOffsetAPI_MakePipeShell Draw Test Harness&#xff1a; C&#xff1a; Draw Test Harness&#xff1a;…

QXlsx Qt操作excel(2)

QXlsx 是一个用于处理Excel文件的开源C库。它允许你在你的C应用程序中读取和写入Microsoft Excel文件&#xff08;.xlsx格式&#xff09;。该库支持多种操作&#xff0c;包括创建新的工作簿、读取和写入单元格数据、格式化单元格、以及其他与Excel文件相关的功能。 关于QXlsx的…

Attention 和 Self-Attention 总结

一、Attention Attention 的核心逻辑是“从关注全部到关注重点”&#xff0c;将有限的注意力集中在重点信息上&#xff0c;从而节省资源&#xff0c;快速获得最有效的信息。 Attention 机制可以更加好的解决序列长距离依赖问题&#xff0c;并且具有并行计算能力。 Attention…

【计算几何】给定一组点的多边形面积

目录 一、说明二、有序顶点集三、无序顶点集3.1 凸多边形3.2 非凸多边形 四、结论 ​ 一、说明 计算多边形面积的方法有很多种。众所周知的多边形&#xff08;如三角形、矩形、正方形、梯形等&#xff09;的面积可以使用简单的数学公式计算。在这篇文章中&#xff0c;我将讨论…

ChatGPT高效提问—prompt常见用法(续篇八)

ChatGPT高效提问—prompt常见用法(续篇八) 1.1 对抗 ​ 对抗是一个重要主题,深入探讨了大型语言模型(LLM)的安全风险。它不仅反映了人们对LLM可能出现的风险和安全问题的理解,而且能够帮助我们识别这些潜在的风险,并通过切实可行的技术手段来规避。 ​ 截至目前,网络…

python web 框架Django学习笔记

2018年5月 python web 框架Django学习笔记 Django 架站的16堂课 MVC架构设计师大部分框架或大型程序项目中一种软件工程的架构模式&#xff0c;把程序或者项目分为三个主要组成部分&#xff0c;Model数据模型、View视图、Controller控制器。 命令及设置相关 创建数据库及中间…

【EAI 014】Gato: A Generalist Agent

论文标题&#xff1a;A Generalist Agent 论文作者&#xff1a;Scott Reed, Konrad Zolna, Emilio Parisotto, Sergio Gomez Colmenarejo, Alexander Novikov, Gabriel Barth-Maron, Mai Gimenez, Yury Sulsky, Jackie Kay, Jost Tobias Springenberg, Tom Eccles, Jake Bruce,…

车载自动化项目:Python

1. 自动化测试用的什么框架&#xff1f; 第一种&#xff1a;PythonSeleniumuittest框架 首先是拿到需求文档&#xff0c;基于这个需求去进行搭建。 用pytestrequestallure 这些第三方库进行编写自动化脚本。 举个例子一般的话整个的一个自动化的搭建是分为6层嘛&#xff1a…

GPIO结构

GPIO简介 GPIO(General Purpose Input Output)通用输入输出口 可配置为8种输入输出模式 引脚电平&#xff1a;0V~3.3V,部分引脚可容忍5V 输出模式下可控制端口输出高低电平,用以驱动LED、控制蜂鸣器、模拟通信协议输出时序等 输入模式下可读取端口的高低电平或电压&#x…