再次感叹c++的生态实在比较差,尤其windows系统。
AES应该算是一个非常知名成熟的加密算法了,但是今天还是被困扰了很久。对方约定的加密模式是CFB,NoPadding,但是基本上开源的c/c++ aes算法都没有支持这样的模式。这个模式确实相对怪异一些,由于CFB可以支持自定义的块长度,所以NoPadding不去填充是完全没问题的,理论上来说。
一开始的想法是基于开源代码来改,但是简单比划了一下就放弃了这个想法,项目火急火燎赶工的时候干这个太扯了,因为要改的地方其实不少,轮次计算和变换移位这些都不是固定模式了,运气不好就是半小时写代码半个月纠错。
得换个思路。java和python干这个肯定是最得心应手的,但是得依赖运行环境所以也不可行,于是就是js了,正好QT的QML天然支持这个。
比较知名的就是crypto-js,找了个web的aes作测试,没问题,还是离线计算的,用Chrome翻了一下果然就是crypto-js,于是就方便挖函数了。这里顺带说一下国内度娘搜出来的在线工具真的不严谨,没有一个完全正确的。
正题
其实完全没必要搞一整套QML,用QJSEngine就可以了,代码量非常少。
QString jsAes(QString x)
{
// js路径
QString filename = "./res/crypto-js.min.js";
QFile jsFile(filename);
if(!jsFile.open(QIODevice::ReadOnly))
{
return "";
}
// 读取js脚本文件
QTextStream out(&jsFile);
QString jsStr = out.readAll();
jsFile.close();
QJSEngine jse;
QJSValue jv = jse.evaluate(jsStr, filename);
if(jv.isError())
printf("unable to load js.\n");
// js是这样调用的
/*const encrypted = CryptoJS.AES.encrypt(message, key, {
mode: CryptoJS.mode.CBC,
paddding: CryptoJS.pad.Pkcs7,
iv: ivkey
});
*/
QString eva_script = QString("CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse('%1'), \
CryptoJS.enc.Utf8.parse('密钥'), { \
mode: CryptoJS.mode.CFB,\
padding: CryptoJS.pad.NoPadding,\
iv: CryptoJS.enc.Utf8.parse('iv')\
}).toString();").arg(x);
QJSValue val = jse.evaluate(eva_script);
QString y = val.toString();
return y;
}
正儿八经的方法应该是读一个func出来,再把枚举类型读出来,然后弄一个valuelist来func call调用函数。但是想想这个其实就当个解释器用,还弄那么麻烦干嘛,直接塞js代码就行了。效果非常好。
后续
后边有时间了还是得把c语言版本的aes完善吧,毕竟这种奇技淫巧也不是长久之计。现在c/c++的开源生态真的不太行,奉献精神从我做起吧。