为什么要保证API安全
- 防止别人随便调用你的api
- 保证传输数据的安全
设计签名
防止别人调用你的API其实并不难,通常做法是在调用API,使用和服务端共用的一个秘钥,根据API请求的名字和API请求的参数算出一个hash来,然后请求的时候带上这个hash。服务端收到请求之后,使用同样的秘钥和算法hash,然后进行比较,如果一致,说明这个API的调用者就是你自己。
NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; //初始化字典
[parameters setObject:@"1" forKey:@"a"]; //参数a
[parameters setObject:@"2" forKey:@"b"]; //参数b
NSArray *parameterKeys = [parameters allKeys]; //得到字典中所有的key
parameterKeys = [parameterKeys sortedArrayUsingSelector:@selector(compare:)];// 字符串编码升序排序
NSString *signData = @"";
for (int i = 0; i < [parameters count]; i++) { //遍历字典
NSString *_key = parameterKeys[i];
NSString * _value = parameters[_key];
signData = [NSString stringWithFormat:@"%@%@=%@", signData, _key, _value]; //将字典中的参数拼接
if (i < ([parameters count] - 1)) {
signData = [signData stringByAppendingString:@"=*="];
}
}
//拼接完之后signData = a=1=*=b=2
NSString *signDataKey = [signData stringByAppendingString:@"KEY"]; //拼接秘钥
NSString *s = [signDataKey md5]; //hash出一个参数
[parameters setObject:s forKey:@"s"]; //添加在请求参数中
这只是很简单一个例子,实际中应当适当增加算法的复杂度。当然这并不能解决所有问题,比如抓到你的API,还是能反复请求同样的API。所以算法中可以增加app的本地信息或者加上时间戳。
这样同样有弊端,如果更换key,那么对旧版本的兼容会带来问题。解决方法就是将秘钥进行可逆加密后一起放在请求参数中,服务端拿到加密后的秘钥和hash之后,解码得到原始的秘钥,然后用它去算hash,再进行比较。
传输安全
互联网发展到今天,大家越来越重视自己的隐私,各大公司也越来越重视数据的安全。传输过程中的数据安全解决方案主要是HPPTS,能够有效防止中间人攻击等。但是API中重要的参数还是要进行加密,常用DES或者AES进行加密。有见过API中密码直接MD5后就行传输,但是MD5在2009年谢涛和冯登国仅用了220.96的碰撞算法复杂度,破解了MD5的碰撞抵抗,该攻击在普通计算机上运行只需要数秒钟(引自维基百科)。
总结
安全是一个永恒的话题,随着各大网站全站https的推进,安全也越来越被重视。签名设计大家必须有,HTTPS希望大家有。
网友评论