AES加密算法说明

2024-09-07 04:28
文章标签 aes 加密算法 说明

本文主要是介绍AES加密算法说明,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

首先,我们得了解AES加密算法的一些基本概念。AES是一种对称加密算法,所谓对称,是说它的加密、解密过程使用相同的密钥。还有非对称加密算法,例如RSA,加密解密使用的是公私钥对。
AES同时是一种分组加密算法,分组的长度一般是16字节(128bit)。分组是什么意思呢?假设我有一段很长的明文T,我没法用AES加密整个T,只能将T分成若干16byte的明文组,接着对这些明文组逐个进行加密,得到一堆密文组,把密文组组合起来,才是最终的密文。如果T的长度并非16byte的整数倍,还需做padding,填充到16byte的整数倍。
AES的密钥长度则必须是16byte(对应AES-128)、24byte(对应AES-192)、32byte(对应AES-256),密钥越长,暴力破解难度越大,算法的安全性更好。如果密钥长度不满足上述要求,也需做padding。
加解密模式,如EBC、CBC等。EBC只是将分组加密的密文简单组合在一起,有很多的弱点(例如密文呈现与明文一样的规律性、可以在不做密钥破译的情况下篡改密文等),不建议使用。用的比较多的是CBC模式,本文也以CBC来示例。
初始化向量,简称IV,用作干扰,IV必须是强伪随机数(java下使用SecureRandom而非Random)。CBC模式下IV的长度必须跟分组长度相同,原因是IV要用来跟第一个明文分组做异或
我们使用python3的Crypto库来写个例子:

from Crypto.Cipher import AES
from Crypto.Random.random import StrongRandom
from Crypto.Util.number import long_to_bytes
from Crypto.Hash import SHA256
from Crypto.Util.Padding import pad, unpadENC = 'utf-8'def str2byte(s: str):return s.encode(ENC)def byte2str(buf: bytes):return buf.decode(ENC)def any2byte(data):return str2byte(data) if isinstance(data, str) else dataclass AESHelper(object):"""docstring for AESHelper"""def __init__(self, key):super(AESHelper, self).__init__()self.key = any2byte(key)self.iv = 'This is an IV456'self.mode = AES.MODE_CBCdef encrypt(self, msg: str | bytes) -> bytes:encrypt_cipher = AES.new(self.key, self.mode, str2byte(self.iv))return encrypt_cipher.encrypt(pad(any2byte(msg), AES.block_size))def decrypt(self, cipher_msg: bytes) -> bytes:decrypt_cipher = AES.new(self.key, self.mode, str2byte(self.iv))return unpad(decrypt_cipher.decrypt(cipher_msg), AES.block_size)def decrypt2str(self, cipher_msg: bytes) -> str:return byte2str(self.decrypt(cipher_msg))

java的例子略有不同,需要说明的是,java8自带的加密算法只支持AES-128,要支持AES-256,得先去oracle的官网下载JCE(java加密扩展)的两个jar包:local_policy.jar和US_export_policy.jar,覆盖jre\lib\security下的同名文件(注意提前做好备份)。
java的例子如下:

//我们这里使用PKCS5Padding而非NoPadding,这样可以省掉手动明文填充的工作
private static final String AES_MODE = "AES/CBC/PKCS5Padding"; //NoPadding
private static void testCipher()
{String pwd = "helloworld";//key size必须是32字节String key = "keytoolskeytoolskeytoolskeytools";String iv = "This is an IV456";try{Cipher encryptCipher = Cipher.getInstance(AES_MODE);javax.crypto.spec.IvParameterSpec sr = new javax.crypto.spec.IvParameterSpec(iv.getBytes());SecretKey k = new SecretKeySpec(key.getBytes(), "AES");encryptCipher.init(Cipher.ENCRYPT_MODE, k, sr);byte[] encText = encryptCipher.doFinal(pwd.getBytes());Cipher decryptCipher = Cipher.getInstance(AES_MODE);decryptCipher.init(Cipher.DECRYPT_MODE, k, sr);String origin = new String(decryptCipher.doFinal(encText));System.out.println("pwd:" + origin);}catch(Exception e){e.printStackTrace();}
}    

padding

padding有一些标准的方法,例如:PKCS5Padding、PKCS7Padding。PKCS5是PKCS7的子集,其假设块大小固定为8字节。

  • ZeroPadding,数据长度不对齐时使用0填充,否则不填充
  • PKCS7Padding,假设数据长度需要填充n(n>0)个字节才对齐,那么填充n个字节,每个字节都是n;如果数据本身就已经对齐了,则填充一块长度为块大小的数据,每个字节都是块大小
  • PKCS5Padding,PKCS7Padding的子集,块大小固定为8字节。

IV和key的保存

有一些要遵循的原则:

  • Key must be secret at all times (must not be anywhere near the database)
  • IV must be different for each record.
  • IV must be “indistinguishable from random” and unpredictable, preferably it must come from the same source as your AES keys; other option is to encrypt some value (different for each record) with a secret key.
  • IV needs not to be secret

所以,IV使用强随机数,跟密文一起存放即可。

那么key呢?key的存放是个难题,建议如下:

  1. 保存在文件里,对文件设置用户权限
  2. 程序启动时,由用户输入一个密码,从而获得key,这个技术称为PBE(password based encryption)

这篇关于AES加密算法说明的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1144049

相关文章

Linux join命令的使用及说明

《Linuxjoin命令的使用及说明》`join`命令用于在Linux中按字段将两个文件进行连接,类似于SQL的JOIN,它需要两个文件按用于匹配的字段排序,并且第一个文件的换行符必须是LF,`jo... 目录一. 基本语法二. 数据准备三. 指定文件的连接key四.-a输出指定文件的所有行五.-o指定输出

Redis中Hash从使用过程到原理说明

《Redis中Hash从使用过程到原理说明》RedisHash结构用于存储字段-值对,适合对象数据,支持HSET、HGET等命令,采用ziplist或hashtable编码,通过渐进式rehash优化... 目录一、开篇:Hash就像超市的货架二、Hash的基本使用1. 常用命令示例2. Java操作示例三

Redis中Set结构使用过程与原理说明

《Redis中Set结构使用过程与原理说明》本文解析了RedisSet数据结构,涵盖其基本操作(如添加、查找)、集合运算(交并差)、底层实现(intset与hashtable自动切换机制)、典型应用场... 目录开篇:从购物车到Redis Set一、Redis Set的基本操作1.1 编程常用命令1.2 集

Python sys模块的使用及说明

《Pythonsys模块的使用及说明》Pythonsys模块是核心工具,用于解释器交互与运行时控制,涵盖命令行参数处理、路径修改、强制退出、I/O重定向、系统信息获取等功能,适用于脚本开发与调试,需... 目录python sys 模块详解常用功能与代码示例获取命令行参数修改模块搜索路径强制退出程序标准输入

MySQL之复合查询使用及说明

《MySQL之复合查询使用及说明》文章讲解了SQL复合查询中emp、dept、salgrade三张表的使用,涵盖多表连接、自连接、子查询(单行/多行/多列)及合并查询(UNION/UNIONALL)等... 目录复合查询基本查询回顾多表查询笛卡尔积自连接子查询单行子查询多行子查询多列子查询在from子句中使

Redis中哨兵机制和集群的区别及说明

《Redis中哨兵机制和集群的区别及说明》Redis哨兵通过主从复制实现高可用,适用于中小规模数据;集群采用分布式分片,支持动态扩展,适合大规模数据,哨兵管理简单但扩展性弱,集群性能更强但架构复杂,根... 目录一、架构设计与节点角色1. 哨兵机制(Sentinel)2. 集群(Cluster)二、数据分片

Springboot项目构建时各种依赖详细介绍与依赖关系说明详解

《Springboot项目构建时各种依赖详细介绍与依赖关系说明详解》SpringBoot通过spring-boot-dependencies统一依赖版本管理,spring-boot-starter-w... 目录一、spring-boot-dependencies1.简介2. 内容概览3.核心内容结构4.

redis和redission分布式锁原理及区别说明

《redis和redission分布式锁原理及区别说明》文章对比了synchronized、乐观锁、Redis分布式锁及Redission锁的原理与区别,指出在集群环境下synchronized失效,... 目录Redis和redission分布式锁原理及区别1、有的同伴想到了synchronized关键字

MySQL 临时表创建与使用详细说明

《MySQL临时表创建与使用详细说明》MySQL临时表是存储在内存或磁盘的临时数据表,会话结束时自动销毁,适合存储中间计算结果或临时数据集,其名称以#开头(如#TempTable),本文给大家介绍M... 目录mysql 临时表详细说明1.定义2.核心特性3.创建与使用4.典型应用场景5.生命周期管理6.注

Java中数组与栈和堆之间的关系说明

《Java中数组与栈和堆之间的关系说明》文章讲解了Java数组的初始化方式、内存存储机制、引用传递特性及遍历、排序、拷贝技巧,强调引用数据类型方法调用时形参可能修改实参,但需注意引用指向单一对象的特性... 目录Java中数组与栈和堆的关系遍历数组接下来是一些编程小技巧总结Java中数组与栈和堆的关系关于