AES密文与明文长度的关系

参考:
https://www.cnblogs.com/adylee/archive/2007/09/14/893438.html
https://blog.csdn.net/liwei16611/article/details/86312599

AES介绍

严格地说,AES和Rijndael加密法并不完全一样(虽然在实际应用中二者可以互换),因为Rijndael加密法可以支持更大范围的区块和密钥长度:AES的区块长度固定为128位,密钥长度则可以是128,192或256位;而Rijndael使用的密钥和区块长度可以是32位的整数倍,以128位为下限,256位为上限。加密过程中使用的密钥是由Rijndael密钥生成方案产生。

AES为分组密码,分组密码也就是把明文分成一组一组的,每组长度相等,每次加密一组数据,直到加密完整个明文。在AES标准规范中,分组长度只能是128位,也就是说,每个分组为16个字节(每个字节8位)。密钥的长度可以使用128位、192位或256位。密钥的长度不同,推荐加密轮数也不同,如下表所示:

AES 密钥长度(32位比特字) 分组长度(32位比特字) 加密轮数
AES-128 4 4 10
AES-192 6 4 12
AES-256 8 4 14

轮数在下面介绍,这里实现的是AES-128,也就是密钥的长度为128位,加密轮数为10轮。
上面说到,AES的加密公式为C = E(K,P),在加密函数E中,会执行一个轮函数,并且执行10次这个轮函数,这个轮函数的前9次执行的操作是一样的,只有第10次有所不同。也就是说,一个明文分组会被加密10轮。AES的核心就是实现一轮中的所有操作。

密钥长度

由于采用了256位AES加密,使用了CBC模式加PKCS #5补齐,所以AES的密文字节长度 = (明文长度 +1) / 16 * 16(即比明文长度大的最小的16的倍数)。
JNCryptor返回的密文长度则是在此基础上再加上66个字节。

返回的密文是二进制数据,无法直接显示。如果需要进一步编码为可显示字符串,则需进行BASE64编码或者十六进制编码。编码后的数据长度会进一步增加(BASE64是增长为4/3倍起的最小的4的倍数,十六进制编码是增长为2倍)。比如,对原文长度在32-47个字节之间的明文,经过AES256JNCryptor加密后的密文长度就是114个字节,再做一次BASE64编码转换成可显示字符就成了152个字符

明文与密文长度关系

  1. 在原始数据长度为 16 的整数倍时
    假如原始数据长度等于 16n,则使用 NoPadding 时加密后数据长度等于 16n,其它情况下加密数据长度等于 16*(n+1)。
  2. 在不足 16 的整数倍的情况下
    假如原始数据长度等于 16n+m [其中 m 小于16],除了 NoPadding 填充之外的任何方式,加密数据长度都等于 16(n+1);

例如:算法/模式/填充(AES/CBC/PKCS5Padding),明文69字符,则密文为69=164+5,其中n为4,m为5,密文长度为16(4+1)=80字节,而如果你再转为base64之后,长度也会变长。

base64长度

Base64编码要求把3个8位字节(38=24)转化为4个6位的字节(46=24),之后在6位的前面补两个0,形成8位一个字节的形式。
如果剩下的字符不足3个字节,则用0填充,输出字符使用'=',因此编码后输出的文本末尾可能会出现1或2个'='。
为了保证所输出的编码位可读字符,Base64制定了一个编码表,以便进行统一转换。编码表的大小为2^6=64,这也是Base64名称的由来。它长度为=bytestring * (4 / 3),不能被3整除的,加到最小被3整除的数 ,如80你需要加到81,结果81*(4/3)=108

实例:
V61234567820200612D102103f,V51234567820200612D102103f
6B6N1qoTEmyJKxQOO6xdwXu2xP+bbnjsAadbDpGuOf5CAwtW8qVNseD4cWlAdX47KwTNNmm1NpMsYCSGuqYuGg==
明文长:53
密文base64:88
计算:53=163+5,16(3+1)=64,64(4/3),补两个0(=)66/34=88

posted @ 2020-12-30 10:18  张占岭  阅读(32594)  评论(2编辑  收藏  举报