这两天弄加密和解密的内容,需要openssl(cocos2dx带有curl用到了openssl)的rsa和aes与java匹配,用base64测试,同时绑定到lua,遇到一些问题记录一下。
openssl和java对RSA的私钥和公钥的编码格式支持上面有些不同,在用的时候需要转换。openssl在读取公钥的时候有2个函数,分别对应了不同的文件格式,可以转换。java默认的RSA填充方式为PKCS1Padding,在openssl选一样即可。如果发现每次加密的密文都不一样不要奇怪,因为这种填充方式会进行随机数填充让生成的密文每次都不一样,如果换成NoPadding填充方式(不填充)那每次生成的密文都是一样的了。密钥长度为1024位时,选用PKCS1Padding填充方式时,明文最大长度为117字节,选用NoPadding时明文最大长度为128字节。
AES在openssl中限定为只处理一个块16字节的方式,不足和多余的需要自己处理。java默认使用的PKCS5Padding填充方式,在用openssl时一样实现下该填充方式就可以了。其实PKCS5Padding和PKCS7Padding填充的数据和处理方式上没什么区别,在概念和定义上面有些不同。我这里没用EVP的函数,使用的AES自身函数。
openssl对Base64的处理也是按照标准来的吧,但是用起来就不太方便了,当结尾有‘=’的时候解码出来的数据会多’\0‘。在作为字符串处理时还好,但如果是2进制数据的话就不对了,所以需要自己手动处理,计算原文长度去除结尾的填充数据。安装Base64的填充方式,原文字节数不是3的倍数的会填充为3的倍数,编码之后字节数为4的倍数,填充的可能情况是1、2个’\0‘在编码后变成了'='。不会填充3个,需要填充3个的话已经是3的倍数了。所以原文长度计算方式:原文长度=编码后长度/4*3-'='的数量。
要说一下cocos2dx在绑定到lua时,要注意2进制数据转换的问题,不能用lua对字符串的处理方式来转换,会把‘\0’字符当成字符串结尾,而截断数据。