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个字符
明文与密文长度关系
- 在原始数据长度为 16 的整数倍时
假如原始数据长度等于 16n,则使用 NoPadding 时加密后数据长度等于 16n,其它情况下加密数据长度等于 16*(n+1)。 - 在不足 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