AES - 关于AES算法 JAVA同C++互解

关于加解密JAVA一般使用的JCE,关于C++可以实现AES加解密的开源项目就多的数不胜数的。
理论上上算法一样,对称密钥一样就能够互相识别了。
相信很多人开始想法都同我一样,起初我JAVA用JCE,C++使用openssl。
结果发现加密出的密文完全不相同。

JCE中AES支持五中模式:CBC,CFB,ECB,OFB,PCBC;
支持三种填充:NoPadding,PKCS5Padding,ISO10126Padding。
不支持SSL3Padding。不支持“NONE”模式。 好原来有模式和填充一说。

在OPENSSL中直接有一个CBC加解密函数。
填充没找到,试过后发现C++加密出的内容比JAVA的要长出一截,前面的内容是完全一样的。
这应该就出现在填充上。本来以为找到问题关键就应该很容易解决的。
结果发现OPENSSL的填充是固定实现的,而我所需要解密的java端代码不能改动。
一条路走不通咱就换条路。最后发现有一个开源项目Botan什么都有而且同JCE十分相似并且满足我要求垮平台。
附:
算法/模式/填充              16字节加密后数据长度      不满16字节加密后长度
AES/CBC/NoPadding           16                        不支持
AES/CBC/PKCS5Padding        32                        16
AES/CBC/ISO10126Padding     32                        16
AES/CFB/NoPadding           16                        原始数据长度
AES/CFB/PKCS5Padding        32                        16
AES/CFB/ISO10126Padding     32                        16
AES/ECB/NoPadding           16                        不支持
AES/ECB/PKCS5Padding        32                        16
AES/ECB/ISO10126Padding     32                        16
AES/OFB/NoPadding           16                        原始数据长度
AES/OFB/PKCS5Padding        32                        16
AES/OFB/ISO10126Padding     32                        16
AES/PCBC/NoPadding          16                        不支持
AES/PCBC/PKCS5Padding       32                        16
AES/PCBC/ISO10126Padding    32                        16 
在原始数据长度为16的整数倍时:
假如原始数据长度等于16*n,则使用NoPadding时加密后数据长度等于16*n,其它情况下加密数据长度等于16*(n+1)。
在不足16的整数倍的情况下:
假如原始数据长度等于16*n+m[其中m小于16],除了NoPadding填充之外的任何方式,加密数据长度都等于16*(n+1);
NoPadding填充情况下,CBC、ECB和PCBC三种模式是不支持的,CFB、OFB两种模式下则加密数据长度等于原始数据长度。

还有一种方案:
在java端采用AES/CBC/PKCS5Padding方式加密的时候,c端要对应的采用CBC模式和PKCS5Padding的填充方式。
我的问题主要就是处在PKCS5Padding的填充方法上面,正确的填充方法应该是:
1.如果明文刚好是16的倍数,则需要在末尾填充长度为16的串,且每个字节的值为OX16。
2.如果明文不是16的倍数,则需要填充为16的倍数。比如abcd123456长度为10,则需要填充6个字节,且每个字节的值为0x06.
填充完成后再进行cbc模式的加密,这样跟java互相兼容就没有问题了。
只需要用cbc加密模式,填充方式用我上面描述的方法,是没有问题的。
源码没什么意义,只是在调用openssl的加密函数do_AES_cbc_encrypt前,将源数据串进行了填充。

你可能感兴趣的:(AES - 关于AES算法 JAVA同C++互解)