AES加解密 您所在的位置:网站首页 aes256加密后的数据长度 AES加解密

AES加解密

2024-02-02 05:10| 来源: 网络整理| 查看: 265

要想学习AES,首先要清楚三个基本的概念:密钥、填充、模式。

1、密钥

密钥是AES算法实现加密和解密的根本。对称加密算法之所以对称,是因为这类算法对明文的加密和解密需要使用同一个密钥。

AES支持三种长度的密钥: 128位,192位,256位

平时大家所说的AES128,AES192,AES256,实际上就是指AES算法对不同长度密钥的使用。

三种密钥的区别:

从安全性来看,AES256安全性最高。从性能看,AES128性能最高。本质原因是它们的加密处理轮数不同。

2、填充

要想了解填充的概念,我们先要了解AES的分组加密特性。 什么是分组加密?

AES算法在对明文加密的时候,并不是把整个明文一股脑的加密成一整段密文,而是把明文拆分成一个个独立的明文块,每一个明文块长度128bit。

这些明文块经过AES加密器复杂处理,生成一个个独立的密文块,这些密文块拼接在一起,就是最终的AES加密的结果。

但这里涉及到一个问题,假如一段明文长度是196bit,如果按每128bit一个明文块来拆分的话,第二个明文块只有64bit,不足128bit。这时候怎么办呢?就需要对明文块进行填充(Padding) 。

几种典型的填充方式:

NoPadding: 不做任何填充,但是要求明文必须是16字节的整数倍。 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} PKCS7Padding原理与PKCS5Padding相似,区别是PKCS5Padding的blocksize为8字节,而PKCS7Padding的blocksize可以为1到255字节

需要注意的是,如果在AES加密的时候使用了某一种填充方式,解密的时候也必须采用同样的填充方式。

3、模式

AES的工作模式,体现在把明文块加密成密文块的处理过程中。AES加密算法提供了五种不同的工作模式:CBC,ECB,CTR,CFB,OFB 模式之间的主题思想是近似的,在处理细节上有一些差别

AES加密算法 - 加密模式

ECB模式   优点:   1.简单;   2.有利于并行计算;   3.误差不会被传送;   缺点:   1.不能隐藏明文的模式;   2.可能对明文进行主动攻击; CBC模式:   优点:   1.不容易主动攻击,安全性好于ECB,适合传输长度长的报文,是SSL、IPSec的标准。   缺点:   1.不利于并行计算;   2.误差传递;   3.需要初始化向量IV CFB模式:   优点:   1.隐藏了明文模式;   2.分组密码转化为流模式;   3.可以及时加密传送小于分组的数据;   缺点:   1.不利于并行计算;   2.误差传送:一个明文单元损坏影响多个单元;   3.唯一的IV; ofb模式:   优点:   1.隐藏了明文模式;   2.分组密码转化为流模式;   3.可以及时加密传送小于分组的数据;   缺点:   1.不利于并行计算;   2.对明文的主动攻击是可能的;   3.误差传送:一个明文单元损坏影响多个单元;

上面四个不同模式原理图链接:https://www.cnblogs.com/adylee/archive/2007/09/14/893438.html

3.1、ECB模式简介

img

2)、CBC模式简介

下图中,IV一般为16字节全0,数据块长度为16字节的整数倍,则在此数据块后附加一个8字节长的数据块,

附加的数据块为:16进制的“80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00”

img

cbc本质上和ecb差别不大,唯一区别是将前一次加密结果,与要加密的内容异或。因此,cbc的并行性较差,因为每次都要等待前一次的结果,而ecb则不用,速度较快。其主要区别仍然看文章开头,原理图看参考链接。

3.2、AES算法ECB模式 生成加密/解密的Key int AES_set_encrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key); int AES_set_decrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key);

参数说明:

参数名称 描述 userKey 用户指定的密码。注意:只能是16、24、32字节。如果密码字符串长度不够,可以在字符串末尾追加一些特定的字符,或者重复密码字符串,直到满足最少的长度 bits 密码位数。即userKey的长度 * 8,只能是128、192、256位。 key 向外输出参数。

如果函数调用成功,返回0,否则是负数。

使用函数AES_ecb_encrypt对数据进行加解密

函数原型:

void AES_ecb_encrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key, const int enc);

函数说明:

AES加密/解密单个数据块(16个字节),ECB模式

参数说明:

参数名称 描述 in 需要加密/解密的数据 out 计算后输出的数据 key 密钥 enc AES_ENCRYPT 代表加密, AES_DECRYPT代表解密 3.3、AES算法CBC模式 生成加密/解密的Key int AES_set_encrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key); int AES_set_decrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key);

参数说明:

参数名称 描述 userKey 用户指定的密码。注意:只能是16、24、32字节。如果密码字符串长度不够,可以在字符串末尾追加一些特定的字符,或者重复密码字符串,直到满足最少的长度 bits 密码位数。即userKey的长度 * 8,只能是128、192、256位。 key 向外输出参数。

如果函数调用成功,返回0,否则是负数。

使用AES_cbc_encrypt对数据进行加解密 void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t length, const AES_KEY *key, unsigned char *ivec, const int enc);

函数说明:

AES加密/解密单个数据块(16个字节),CBC模式

参数说明:

参数名称 描述 in 输入数据。长度任意。 out 输出数据。能够容纳下输入数据,且长度必须是16字节的倍数。 length 输出数据的实际长度。 key 使用AES_set_encrypt/decrypt_key生成的Key。 ivec 可读写的一块内存。长度必须是16字节。 enc 是否是加密操作。AES_ENCRYPT表示加密,AES_DECRYPT表示解密。

​ 这个函数比AES_encrypt多了一个ivec参数,ivec的内容可以任意指定,但是加密和解密操作必须使用同样的数据。在AES_cbc_encrypt底层,实际上是每16个字节做一次处理,先和ivec做异或运算,然后调用AES_encrypt函数进行加密。 AES_cbc_encrypt在加密的过程中会修改ivec的内容,因此ivec参数不能是一个常量,而且不能在传递给加密函数后再立马传递给解密函数,必须重新赋值之后再传递给解密函数。

关于输出数据的长度 输出数据缓冲区的长度必须是16字节的倍数,加密完成后,比输入长度多出来的输出数据是不可以丢弃的。因此,存档的时候,需要记录原始数据的长度

关于输入数据的长度不必是16字节的倍数(做个备忘): 下面是AES_cbc_encrypt函数的底层实现代码

... //处理16字节倍数的数据 while (len >= 16) { for (n = 0; n < 16; ++n) out[n] = in[n] ^ iv[n]; (*block) (out, out, key); //调用AES_encrypt处理数据 iv = out; len -= 16; in += 16; out += 16; } //当数据小于16字节的时候,进入下面的循环 while (len) { for (n = 0; n < 16 && n < len; ++n) out[n] = in[n] ^ iv[n]; for (; n < 16; ++n) out[n] = iv[n]; //使用ivec补齐不足16字节的部分 (*block) (out, out, key); //调用AES_encrypt处理数据 iv = out; if (len


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有