作者:张一环
链接:http://www.zhihu.com/question/40159698/answer/85121831
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
链接:http://www.zhihu.com/question/40159698/answer/85121831
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
这个一般意义上来说就是防盗链是吧。简单提一些方法,从接口的设计开始。
1. HTTPS。首先接口建议使用 HTTPS 协议,这样至少会给破解者在抓包的时候提高一些难度。上面也有答主提到其它协议,实现起来有难度不说,实际上也没有这个必要吧;
2. 接口参数的设置。这个很重要,有必要设置一些验证参数。这里面有两种常见的做法。
最后,要是对方完全破解了你的防盗链措施,并且在客户端完全模拟你客户端的行为的话。那我还能说什么呢…只能说你的产品非常有价值。
1. HTTPS。首先接口建议使用 HTTPS 协议,这样至少会给破解者在抓包的时候提高一些难度。上面也有答主提到其它协议,实现起来有难度不说,实际上也没有这个必要吧;
2. 接口参数的设置。这个很重要,有必要设置一些验证参数。这里面有两种常见的做法。
- MD5 校检值形式。设置一个 sign 参数,这个参数是一个 MD5 值,其原文是请求的其它参数和一些固定的加密字符串(盐)的组合。我更建议再加上一个时间 tm 参数,可以是当前的时间戳,把这个 tm 参数也融合到 sign 里面去,乐视网的很多接口和视频地址就是采用的此形式。
int id = 10000; // 假设请求的参数为 id ,假设为 10000
int tm = System.currentTimeMillis() / 1000;
String sign = md5(id + tm + "salt"); // md5 是实现取 md5 值(32 字节的 Hex 文本)的函数,salt 是加密盐,建议修改长一点。
String api = "https://www.xxx.com/api?id=" + id + "&tm=" + tm + "&sign=" + sign;
// 请求 API
- 算法加密字符串形式。和上面的 MD5 差不多,只不过是把参数用 AES / DES 之类的对称或者非对称算法加密之后作为一个验证参数。服务器接到请求之后,解密参数,看看是否正确。这里面还可以加入一些客户端的本地信息作为判断依据。优酷和腾讯视频就是采用的此形式。
- 对于 Android 程序,我建议把加密的部分放到 so (C 动态库)文件中去,这样的话破解者即使想破解,也得用上反汇编工具。对 so 文件,两个建议:函数结构要混淆,函数名要混淆,入口点不要用默认的;so 文件要做验证!一定要做验证,否则破解者根本不用破解,直接拿你的 so 文件去使用,你就相当于直接给他写好盗链模块了…
- 对于 Flash,建议使用 FlasCC(Alchemy)技术,将 C 模块植入,这比上面的 so 文件更难破解,打开过很多 Alchemy 技术的 Flash 文件,头都大了。
- User-Agent 和 Referer 限制。限制这些作用不大,但能有效地防止 Web 端直接盗链。除非对方实现了 Socket,但有这个技术的话,何必还来盗链你呢~
- 验证登录。这里所说登录不一定是账户登录,还可以是设备 device 登录。可以给用户设备分配一个唯一的 device id,用来验证。这些信息可以放在 Cookie 里,也可以直接作为一个参数。
- 请求频次限制。对单个 device id 可以设置其请求频率,device id 很容易伪造,所以建议服务器生成,本地只记录和传递。另外上面有些答主提到了 IP 频率限制。我不建议对 IP 进行太多的限制,如果限制频率太低,这会影响正常用户使用,因为国内运营商环境复杂,很多用户共用一个出口 IP 的现象非常常见。但也千万别因此就相信了 HTTP Header 中的 X-Forwarded-For,这个参数是可以直接伪造的。
- 返回的结果可以加密。然后客户端在本地进行解密,解密的代码最好也放到 so 文件中去。
最后,要是对方完全破解了你的防盗链措施,并且在客户端完全模拟你客户端的行为的话。那我还能说什么呢…只能说你的产品非常有价值。