腾讯广告实时交易平台在向竞价胜出一方返回成交价的时候,先对价格进行TEA加密,再对密文进行BASE64编码,接收方先对BASE64解码,再对密文解密,双方事先约定密钥。鹅厂官网提供了C#、C++、JAVA和PHP的解密代码包,无奈原有平台都是基于GO语言的,虽然能够调C++的静态库(libdecrypt.a),但开发工具是JetBrains GoLand,跑在Windows 7下后期难以调试,在虚拟机下跑linux版严重影响开发效率,不得不尝试改写为GO语言直接调用来的酣畅淋漓,主要缘由仍是太穷买不起MacBook。linux
本来以为是个小活儿分分钟就能够搞定,没想到是个花了十二个工时的脏活累活,压根不是抄抄写写那么简单,一个坑接着一个坑。libdecrypt.a静态库在编译的时候没有加入调试信息彻底没法跳入,jar却是能够反编译看到源码,但编译器对部分中间变量作了优化处理,尤为对部分逻辑还原的带有强烈的我的感情色彩,IDEA和Java Decompiler两个工具自说自话,连被优化掉的变量命名都那么使人忍俊不由。git
// IntelliJ IDEA if(nInBufLen % 8 == 0 && nInBufLen >= 16 && pKey.length == 16) { // 省略 } // Java Decompiler if ((nInBufLen % 8 != 0) || (nInBufLen < 16) || (pKey.length != 16)) { return null; } // IntelliJ IDEA dest_buf[j] ^= pInBuf[var18 + j]; // Java Decompiler int tmp250_249 = j; byte[] tmp250_247 = dest_buf; tmp250_247[tmp250_249] = ((byte)(tmp250_247[tmp250_249] ^ pInBuf[(nBufPos + j)]));
调试的时候问题百出,只能左手跑JetBrains GoLand,右手跑IntelliJ IDEA,两边同时Step Out | Into跟踪,检查输入输出发现问题再解决问题,数次打算放弃名正言顺直接调用C++库,毕竟项目进度摆在那里男人何苦为难本身,不过坚持不懈是我惟一拿得出手值得炫耀的品格了,何况没准这个问题或许就是最后一个问题了呢。工具
罗里吧嗦说说遇到的坑吧!开发工具
坑一:GO语言作<<操做的时候高位溢出部分舍弃,C\C++和JAVA补1,须要对0xffffffff取反之后再作位置或操做;优化
坑二:GO语言“+”优先级高于“^”,在改写C\C++和JAVA表达式的时候须要加括号提高优先级,如:z -= int64(y << 4) + int64(c) ^ (y + sum ^ ((y >> 5) + int64(d)));编码
坑三:已知a := []int{1, 2, 3, 4, 5, 6}; b := a[:],两者指向同一内存空间,没有达到b = (int[])a.clone() 的目的;加密
坑四:GO语言没有“>>>”无符号右移运算符;调试
坑五:GO语言[]byte取值范围0-255,与JAVA的byte[]对应的是[]int8;code
代码下载地址:https://gitee.com/gonglibin/codes/67lj5sv43bdegrm2ah81x21内存