信息安全(一)
思维导图
一、AES加解密
1.概述
1.1 概念
AES: 高级加密标准(Advanced Encryption Standard)是一种对称加密的区块加密标准。
(1)替代DES的新一代分组加密算法
(2)支持三种长度密钥:128、192、256位
1.2 加解密过程
分组加密、分组解密
1.2.1 分组加解密
将待加解密的内容按照128位分组,将密钥按照128位、192位、256位分组,分别将分组后的明文与相应分组后的密钥加解密。
(1)明文与密钥分组
-
明文分组
每组长度相等,都是128位(16字节) -
密钥分组
有128位、192位、256位,推荐加密轮数分别为 10、12、14
(2)密钥组处理
以每组128位为例:
- 推荐加密轮数为10,前9次执行操作一样,第10次有所不同
(3)加密
- 明文与密钥分组后,对每组如下操作:
明文组与密钥组处理 ----> 轮密钥加 ----> 10轮加密 ---->
密文组
(4)解密
- 对每组如下操作:
密文组 ----> 轮密钥加 ----> 10轮加密 ---->
明文组
1.2.2 4种操作

(1)AddRoundKey (轮密钥加)
-
矩阵中的每一个字节都与该次轮密钥(Round Key)做XOR运算
-
每个子密钥由密钥生成方案产生
(2)SubBytes(字节替代)
- 通过非线性的替代函数,用查找表的方式把每个字节替换成对应的字节。
(3)ShiftRows(行移位)
- 将矩阵中的每个横列进行循环式移位
(4)MixColumns (列混淆)
-
为了充分混合矩阵中各个直行
-
使用线性转换来混合每列的4个字节
1.2.2 明文填充模式
(1)为什么要填充?
如一段明文长度是192位,如果按每128位拆,第二个明文块只有64位,不足128位,就需要对明文块进行填充
(2)分类
-
NoPadding
不做任何填充,但是要求明文必须是16字节(128bit)的整数倍。 -
PKCS5Padding(默认)
如果明文块少于16个字节(128bit),在明文块末尾补足相应数量的字符。
且每个字节的值等于缺少的字符数。
如:明文:{1,2,3,4,5,a,b,c,d,e},缺少6个字节,则补全为{1,2,3,4,5,a,b,c,d,e,6,6,6,6,6,6}
- ISO10126Padding
如果明文块少于16个字节(128bit),在明文块末尾补足相应数量的字符。
最后一个字符值等于缺少的字符数,其他字符填充随机数。
如明文:{1,2,3,4,5,a,b,c,d,e},缺少6个字节,则可能补全为{1,2,3,4,5,a,b,c,d,e,5,c,3,G,$,6}
1.3 Java实现
注意: AES加密包含Base64加密
加密: AES加密 -> Base64加密 -> 密文解密: Base64解密 -> AES解密 -> 明文测试地址:http://tool.chacuo.net/cryptaes
1.3.1 Java代码
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Base64Utils;import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;/*** AES加密工具类* @author kevin*/
public class AESUtil {/*** 日志相关*/private static final Logger LOGGER = LoggerFactory.getLogger(AESUtil.class);/*** 编码*/private static final String ENCODING = "UTF-8";/*** 算法定义*/private static final String AES_ALGORITHM = "AES";/*** 指定填充方式*/private static final String CIPHER_PADDING = "AES/ECB/PKCS5Padding";private static final String CIPHER_CBC_PADDING = "AES/CBC/PKCS5Padding";/*** 偏移量(CBC中使用,增强加密算法强度)*/private static final String IV_SEED = "1234567812345678";private static final String AES_KEY = "equ6drp6nrwmgf1t";/*** AES加密* @param content 待加密内容*/public static String encrypt(String content){if(StringUtils.isBlank(content)){LOGGER.info("AES encrypt: the content is null!");return null;}//判断秘钥是否为16位if(StringUtils.isNotBlank(AES_KEY) && AES_KEY.length() == 16){try {//对密码进行编码byte[] bytes = AES_KEY.getBytes(ENCODING);//设置加密算法,生成秘钥SecretKeySpec skeySpec = new SecretKeySpec(bytes, AES_ALGORITHM);// "算法/模式/补码方式"Cipher cipher = Cipher.getInstance(CIPHER_PADDING);//选择加密cipher.init(Cipher.ENCRYPT_MODE, skeySpec);//根据待加密内容生成字节数组byte[] encrypted = cipher.doFinal(content.getBytes(ENCODING));//返回base64字符串return Base64Utils.encodeToString(encrypted);} catch (Exception e) {LOGGER.info("AES encrypt exception:" + e.getMessage());throw new RuntimeException(e);}}else {LOGGER.info("AES encrypt: the AES_KEY is null or error!");return null;}}/*** 解密* @param content 待解密内容*/public static String decrypt(String content){if(StringUtils.isBlank(content)){LOGGER.info("AES decrypt: the content is null!");return null;}//判断秘钥是否为16位if(StringUtils.isNotBlank(AES_KEY) && AES_KEY.length() == 16){try {//对密码进行编码byte[] bytes = AES_KEY.getBytes(ENCODING);//设置解密算法,生成秘钥SecretKeySpec skeySpec = new SecretKeySpec(bytes, AES_ALGORITHM);// "算法/模式/补码方式"Cipher cipher = Cipher.getInstance(CIPHER_PADDING);//选择解密cipher.init(Cipher.DECRYPT_MODE, skeySpec);//先进行Base64解码byte[] decodeBase64 = Base64Utils.decodeFromString(content);//根据待解密内容进行解密byte[] decrypted = cipher.doFinal(decodeBase64);//将字节数组转成字符串return new String(decrypted, ENCODING);} catch (Exception e) {LOGGER.info("AES decrypt exception:" + e.getMessage());throw new RuntimeException(e);}}else {LOGGER.info("AES decrypt: the AES_KEY is null or error!");return null;}}/*** AES_CBC加密* @param content 待加密内容*/public static String encryptCBC(String content){if(StringUtils.isBlank(content)){LOGGER.info("AES_CBC encrypt: the content is null!");return null;}//判断秘钥是否为16位if(StringUtils.isNotBlank(AES_KEY) && AES_KEY.length() == 16){try {//对密码进行编码byte[] bytes = AES_KEY.getBytes(ENCODING);//设置加密算法,生成秘钥SecretKeySpec skeySpec = new SecretKeySpec(bytes, AES_ALGORITHM);// "算法/模式/补码方式"Cipher cipher = Cipher.getInstance(CIPHER_CBC_PADDING);//偏移IvParameterSpec iv = new IvParameterSpec(IV_SEED.getBytes(ENCODING));//选择加密cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);//根据待加密内容生成字节数组byte[] encrypted = cipher.doFinal(content.getBytes(ENCODING));//返回base64字符串return Base64Utils.encodeToString(encrypted);} catch (Exception e) {LOGGER.info("AES_CBC encrypt exception:" + e.getMessage());throw new RuntimeException(e);}}else {LOGGER.info("AES_CBC encrypt: the AES_KEY is null or error!");return null;}}/*** AES_CBC解密* @param content 待解密内容*/public static String decryptCBC(String content){if(StringUtils.isBlank(content)){LOGGER.info("AES_CBC decrypt: the content is null!");return null;}//判断秘钥是否为16位if(StringUtils.isNotBlank(AES_KEY) && AES_KEY.length() == 16){try {//对密码进行编码byte[] bytes = AES_KEY.getBytes(ENCODING);//设置解密算法,生成秘钥SecretKeySpec skeySpec = new SecretKeySpec(bytes, AES_ALGORITHM);//偏移IvParameterSpec iv = new IvParameterSpec(IV_SEED.getBytes(ENCODING));// "算法/模式/补码方式"Cipher cipher = Cipher.getInstance(CIPHER_CBC_PADDING);//选择解密cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);//先进行Base64解码byte[] decodeBase64 = Base64Utils.decodeFromString(content);//根据待解密内容进行解密byte[] decrypted = cipher.doFinal(decodeBase64);//将字节数组转成字符串return new String(decrypted, ENCODING);} catch (Exception e) {LOGGER.info("AES_CBC decrypt exception:" + e.getMessage());throw new RuntimeException(e);}}else {LOGGER.info("AES_CBC decrypt: the AES_KEY is null or error!");return null;}}/*** 获取随机AES密钥*/private static String getAESKey(){return RandomStringUtils.random(16, "abcdefghijklmnopqrstuvwxyz1234567890");}public static void main(String[] args) {// AES支持三种长度的密钥:128位、192位、256位。// 代码中这种就是128位的加密密钥,16字节 * 8位/字节 = 128位。String aesResult = encrypt("测试AES加密");System.out.println("AES加密结果:" + aesResult);System.out.println();System.out.println("---------解密---------");String decrypt = decrypt(aesResult);System.out.println("AES解密结果:" + decrypt);System.out.println();System.out.println("--------AES_CBC加密解密---------");String cbcResult = encryptCBC("测试AESCBC加密");System.out.println("AES_CBC加密结果:" + cbcResult);System.out.println();System.out.println("---------AES_CBC解密---------");String cbcDecrypt = decryptCBC(cbcResult);System.out.println("AES_CBC解密结果:" + cbcDecrypt);System.out.println();}
}
1.3.2 执行结果
AES加密结果:CSx/Cg6F7paoo9J7AujBYg==---------解密---------
AES解密结果:测试AES加密--------AES_CBC加密解密---------
AES_CBC加密结果:hmlwSKLW91JhGMqEFozBLzidi6YRVjei0Hw1QkW07ac=---------AES_CBC解密---------
AES_CBC解密结果:测试AESCBC加密
1.3.3线上验证
验证地址:http://tool.chacuo.net/cryptaes

另附安卓代码实现,如下:
AES加密(二) — Aes256带偏移量加/解密
下一篇跳转–信息安全(一)
本篇文章主要参考链接如下:
参考链接1-Java实现加密(一)AES加解密
持续更新中…
随心所往,看见未来。Follow your heart,see light!
欢迎点赞、关注、留言,一起学习、交流!
相关文章:
信息安全(一)
思维导图 一、AES加解密 1.概述 1.1 概念 AES: 高级加密标准(Advanced Encryption Standard)是一种对称加密的区块加密标准。 (1)替代DES的新一代分组加密算法 (2)支持三种长度密钥&#x…...
企业多会场视频直播(主会场、分会场直播)实例效果
阿酷TONY 2023-2-16 长沙 活动直播做多会场切换功能(主会场、分会场、会场一、会场二、会场三自由切换) 企业多会场视频直播(主会场、分会场直播)实例效果 特点:支持PC端,也支持移动端观看,会…...
线性代数速览(一)行列式
文章目录行列式🌻 行列式的定义🌼 行列式的性质🌷 一些定理🥀 行列式的计算🌺 克莱姆法则行列式 行列式的本质,就是一个数值。 🌻 行列式的定义 有三种定义:1、按行展开ÿ…...
恭喜山东翰林“智慧园区管理系统”获易知微可视化设计大赛二等奖
数字化经济发展是全球经济发展的重中之重,“数字孪生(Digital Twin)”这一词汇正在成为学术界和产业界的一个热点。数字孪生作为近年来的新兴技术,其与国民经济各产业融合不断深化,推动着各大产业数字化、网络化、智能…...
gulp简单使用
gulp gulp的核心理念是task runner 可以定义自己的一系列任务 等待任务被执行 基于文件stream的构建流 我们可以使用gulp的插件体系来完成某些任务 webpack的核心理念是module bundler webpack是一个模块化的打包工具 可以使用各种各样的loader来加载不同的模块 可以使用各种…...
ce认证机构如何选择?
CE认证想必大家都已经有所了解,它是产品进入欧盟销售的通行证,那么我们在办理CE认证时该怎么进行选择?带大家了解一下CE认证机构,以及该怎么去进行选择? 以下信息由证果果编辑整理,更多认证机构信息请到证果果网站查看。找机构…...
全网招募P图高手!阿里巴巴持续训练鉴假AI
P过的证件如何鉴定为真?三千万网友都晒出了与梅西的合影?图像编辑技术的普及让人人都能P图,但也带来“假图”识别难题,甚至是欺诈问题。 为此,阿里安全联合华中科技大学国家防伪工程中心、国际文档分析识别方向的唯一顶…...
webrtc QOS笔记一 Neteq直方图算法浅读
webrtc QOS笔记一 Neteq直方图算法浅读 文章目录webrtc QOS笔记一 Neteq直方图算法浅读Histogram Algorithm获取目标延迟遗忘因子曲线Histogram Algorithm DelayManager::Update()->Histogram::Add() 会根据计算的iat_packet(inter arrival times, 实际包间间隔 / 打包时长…...
细分和切入点
本文重点介绍做SEO网站细分和切入点的方法:当我们的行业和关键词竞争性比较大的时候,我们可以考虑对行业或者产品做细分,从而找到切入点。可以按照以下三个方面进行细分。1、按城市细分例如:A:餐饮培训,当前…...
iOS创建Universal Link
iOS 9之前,一直使用的是URL Schemes技术来从外部对App进行跳转,但是iOS系统中进行URL Schemes跳转的时候如果没有安装App,会提示无法打开页面的提示。 iOS 9之后起可以使用Universal Links技术进行跳转页面,这是一种体验更加完美的…...
RuoYi-Vue搭建(若依)
项目简介 RuoYi-Vue基于SpringBootVue前后端分离的Java快速开发框架1.前端采用Vue、Element UI2.后端采用Spring Boot、Spring Security、Redis & Jwt3.权限认证使用Jwt,支持多终端认证系统4.支持加载动态权限菜单,多方式轻松权限控制5.高效率开发&a…...
进程组和用处
进程组:一个或多个进程的集合,进程组id是一个正整数。组长进程:进程组id 进程id组长进程可以创建一个进程组,创建该进程组的进程,终止了,只要进程组有一个进程存在,进程组就存在,与…...
Nacos集群+Nginx负载均衡
搭建Nacos集群 注意: 3个或3个以上Nacos节点才能构成集群。要求服务器内存分配最好大于6G以上(如果不够则需修改nacos启动脚本中的默认内存配置)根据nacos自带的mysql建库脚本建立对应数据库(/conf/nacos-mysql.sql)如果是三台服…...
TypeScript 学习之类型兼容
TypeScript 的类型兼容性是基于结构子类型的。 结构类型是一种只使用其成员来描述类型的方式。 interface Named {name: string; }class Person {name: string; }let p: Named; p new Person();// 赋值成功,因为都是结构类型,只要Person 类型的包含 Nam…...
Linux软件管理RPM
目录 前言 RPM软件管理程序:rpm RPM默认安装的路径 PRM讲解前准备工作 RPM安装(install) RPM查询(query) RPM卸载(erase) RPM升级与更新(upgrade/freshen) RPM重…...
01背包问题
背包问题的递归解决过程如下: 第一步明确思路 在解决问题之前,为描述方便,首先定义一些变量:Vi表示第 i 个物品的价值,Wi表示第 i 个物品的体积,定义V(i,j):当前背包容量 j,前 i 个…...
14_FreeRTOS二值信号量
目录 信号量的简介 队列与信号量的对比 二值信号量 二值信号量相关API函数 实验源码 信号量的简介 信号量是一种解决同步问题的机制,可以实现对共享资源的有序访问。 假设有一个人需要在停车场停车 1.首先判断停车场是否还有空车位(判断信号量是否有资源) 2.停车场正好…...
JavaScript随手笔记---轮播图(点击切换)
💌 所属专栏:【JavaScript随手笔记】 😀 作 者:我是夜阑的狗🐶 🚀 个人简介:一个正在努力学技术的CV工程师,专注基础和实战分享 ,欢迎咨询! &#…...
机器人学 markdown数学公式常用语法
参考链接1 本文包含了markdown常用的数学公式,按照目录可查询选用 初始类 行内数学公式均用两个符号包裹行间数学公式均用两个符号包裹 行间数学公式均用两个符号包裹行间数学公式均用两个符号包裹,用于表示重要的、需在行间单独列出的公式 $行内数学…...
如何使用 Python 语言来编码和解码 JSON 对象
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,易于人阅读和编写。 JSON 函数 使用 JSON 函数需要导入 json 库:import json。 函数 描述 json.dumps 将 Python 对象编码成 JSON 字符串 json.loads 将已编码的 JSON 字符串解码为 Pyth…...
Java 语言特性(面试系列1)
一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...
React第五十七节 Router中RouterProvider使用详解及注意事项
前言 在 React Router v6.4 中,RouterProvider 是一个核心组件,用于提供基于数据路由(data routers)的新型路由方案。 它替代了传统的 <BrowserRouter>,支持更强大的数据加载和操作功能(如 loader 和…...
vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...
使用SSE解决获取状态不一致问题
使用SSE解决获取状态不一致问题 1. 问题描述2. SSE介绍2.1 SSE 的工作原理2.2 SSE 的事件格式规范2.3 SSE与其他技术对比2.4 SSE 的优缺点 3. 实战代码 1. 问题描述 目前做的一个功能是上传多个文件,这个上传文件是整体功能的一部分,文件在上传的过程中…...
【Linux】Linux安装并配置RabbitMQ
目录 1. 安装 Erlang 2. 安装 RabbitMQ 2.1.添加 RabbitMQ 仓库 2.2.安装 RabbitMQ 3.配置 3.1.启动和管理服务 4. 访问管理界面 5.安装问题 6.修改密码 7.修改端口 7.1.找到文件 7.2.修改文件 1. 安装 Erlang 由于 RabbitMQ 是用 Erlang 编写的,需要先安…...
《信号与系统》第 6 章 信号与系统的时域和频域特性
目录 6.0 引言 6.1 傅里叶变换的模和相位表示 6.2 线性时不变系统频率响应的模和相位表示 6.2.1 线性与非线性相位 6.2.2 群时延 6.2.3 对数模和相位图 6.3 理想频率选择性滤波器的时域特性 6.4 非理想滤波器的时域和频域特性讨论 6.5 一阶与二阶连续时间系统 6.5.1 …...
高分辨率图像合成归一化流扩展
大家读完觉得有帮助记得关注和点赞!!! 1 摘要 我们提出了STARFlow,一种基于归一化流的可扩展生成模型,它在高分辨率图像合成方面取得了强大的性能。STARFlow的主要构建块是Transformer自回归流(TARFlow&am…...
归并排序:分治思想的高效排序
目录 基本原理 流程图解 实现方法 递归实现 非递归实现 演示过程 时间复杂度 基本原理 归并排序(Merge Sort)是一种基于分治思想的排序算法,由约翰冯诺伊曼在1945年提出。其核心思想包括: 分割(Divide):将待排序数组递归地分成两个子…...
