背景
年前有款很火爆红包小程序,只要普通话标准,说对了口令即可领取红包。
在娱乐的过程中发现,小额的红包很轻松就可以领了,大额的无论怎么尝试也领不了,深入探究后发现里面有点猫腻,即后台可以设定领取红包的难度,以及可领取数量,大额的红包便成了营销手段,迅速吸粉等。好像岔开话题了,我们来言归正传。
领取的过程中顺便抓包看了一下请求的数据,发现安全那块做得不是很完善,发现有机可乘,便写了一个程序来篡改数据模拟说口令领红包。
后来和经理聊了一下这款小程序后,经理觉得可以复制一个,我们便开工进行开发了。开发的过程中需把安全这个问题考虑进去,因为涉及的都是金钱。
算法与代码
客户端+后端 校验数据完整性——签名
签名算法是参考微信支付签名的算法
小程序代码
-
/**
-
* 签名
-
* @param data 提交的数据
-
* @param key 安全密钥
-
* @returns {string}
-
*/
-
signature: function (data, key) {
-
var n = null, d = {}, str = '', s = ''
-
n = Object.keys(data).sort()
-
for (var i in n) {
-
d[n[i]] = data[n[i]]
-
}
-
for (var k in d) {
-
if (d[k] === '') continue
-
if (str != '') str += '&'
-
str += k + '=' + encodeURI(d[k])
-
}
-
str += '&key=' + key
-
s = util.hex_md5(str).toUpperCase() // 这儿是进行MD5加密并转大写
-
return s
-
}
PHP代码
-
/**
-
* 获取签名
-
* @param $data 提交的数据
-
* @param $key 安全密钥
-
* @return bool
-
*/
-
function signature($data, $key) {
-
ksort($data);
-
$str = '';
-
foreach ($data as $k => $v) {
-
if ($v === '') continue;
-
if ($str !== '') $str .= '&';
-
if ( 'UTF-8' === mb_detect_encoding($v)) {
-
$v = rawurlencode($v);
-
}
-
$str .= "{$k}={$v}";
-
}
-
$str .= '&key=' . $key;
-
$signature = md5($str);
-
$signature = strtoupper($signature);
-
return $signature;
-
}
使用方法
小程序中封装一个网络请求函数,把生成签名的功能加进即可
PHP中在初始化的时候校验请求的数据以及签名,对比生成的签名是否一致,不一致返回错误,以下是PHP代码截图
最后说明一下签名密钥,这个是自己生成的,需要客户端+服务端一致,应该直接保存在小程序配置中,不能暴露!不能暴露!不能暴露!
没有百分百的安全,如果破解者懂得逆向工程的话,算法+密钥还是能被拿到的,但对于目前来说至少能给数据穿一件外衣。