从nodejs的AES加密解密之后文件大小不一致的问题谈谈AES加密中的补位

一、AES补位知识

  针对 AES 加密的实现过程,一般都会用到补位。AES 加密的原数据长度要求是 16 的整数倍,但实际操作过程中并不能保证每次待加密的数据长度都能是 16 的整数倍,所以这时候就需要进行补位,再进行加密才能得到正确的加密数据。

  常用的补位方式主要:NoPadding,zeroPadding,PKCS5Padding,PKCS7Padding四种方式。其中PKCS5Padding和PKCS7Padding使用起来一样。

  NoPadding:不进行补位操作,保持源数据。

  zeroPadding:末尾补0操作。对于源数据长度不是16的整数倍时,在末尾补0至长度为16的整数倍;

  另外一种情况是源数据长度正好是16的整数倍时,需要在数据末尾补16个0。(需注意!!!!!)

  PKCS5Padding :对于源数据长度不是 16 的整数倍时,在末尾补(16 - src_len % 16) 至长度为16的整数倍;比如差3为16的整数倍,那么就部3个3。

  另外一种情况是源数据长度正好是16的整数倍时,需要在数据末尾补16个16。(需注意!!!!!)

  PKCS7Padding:  与PKCS5Padding使用相同。

二、问题描述:

  之前做大文件的分片AES加密解密,发现office文件,每次打开都会报文件损坏的提示,然后查看原文件和解密后的文件发现两个文件大小不一致。文件的md5值不一样。所以猜测文件是有了变化。

  试了很多种方式,比如IV的偏移向量等,发现还是不行,后来看到有个padding(补位)没用到,所以猜测通过上面的AES补位分析,发现就是因为不满 16 的倍数时,补了相应字节的原因。

三、解决方案:

  并且后来还发现,比如:

  1、文件为一个分片,文件字节少8成为16的倍数,那么加密之后形成的文件就补位了8个8;然后编辑发现文件最后多了8个BS字符(ASCII码表看下方)

  2、文件为多个分片,比如3个分片,最后一个分片少9成为16倍数,那么加密之后文件就多了 2*16 + 9 = 41个字节

  了解了补位规则所以处理就简单了,在解密之后获取 buffer 最后一个字节的值,比如16-16-9,那么每次分片解密之后,把最后补位的那些16-16-9字节先删掉之后,再合并成新文件即可。

  亲测完美完成,并且加密解密之后文件md5值一样,所以有效。

  ASCII码一览表,ASCII码对照表:http://c.biancheng.net/c/ascii/

从nodejs的AES加密解密之后文件大小不一致的问题谈谈AES加密中的补位