日前在工作中遇到AES算法服务器端和iOS端进行联调,发现加密结果不能一致。最后终于解决,记录一下以备将来查询。
原因
Java的默认crypto类,AES算法使用PKCS5Padding 填充模式,而iOS使用PKCS7Padding填充模式。
Server Cipher.init方法采用了AES参数
iOS 采用了kCCOptionECBMode|kCCOptionPKCS7Padding。
从表面上看,Server与iOS进行联调时以为是填充模式出了问题。但其实是iOS的Key转成byte[]时,算法有误导致。
Cipher.init 的参数AES 与 AES/ECB/PKCS5padding 是一致的。
PKCS7Padding
因为加密算法的需求,明文字节必须按照block进行填充对齐,才能方便进行加密运算。
PKCS #7 填充字符串由一个字节序列组成,每个字节填充该填充字节序列的长度。假定块长度为 8,数据长度为 9,数据: FF FF FF FF FF FF FF FF FFPKCS7 填充: FF FF FF FF FF FF FF FF FF 07 07 07 07 07 07 07
如果要填充8个字节,那么填充的字节的值就是0×8;要填充7个字节,那么填入的值就是0×7;以此类推
01 02 02 03 03 03 04 04 04 04 05 05 05 05 05 etc.
假设block为8个字节,明文为64各字节,那么需要额外补8个0x08.
这样的好处是,根据最后一个byte的填充值即可知道填充字节数。
PKCS7Padding VS PKCS5Padding
区别很简单,PKCS5Padding的blocksize为8字节,而PKCS7Padding的blocksize可以为1到255字节