iOS技术交流园iOS知识iOS开发收集

华山论剑之iOS签名那点事

2016-06-10  本文已影响972人  神经骚栋
宁愿做过了后悔,也不要错过了后悔。
用团队的力量打开走向成功的大门

问题缘由:对于大多数初学者来说,签名一直都是一种高深莫测的技术,不是因为有多么的难,而是因为你不知道它干什么用的.那么签名到底是干什么用的呢?项目可能有对服务器的数据请求,有网络请求就会有网络接口,别人可以通过拦截,知道你的网络接口,然后不断的恶意的攻击的服务器,造成服务器的瘫痪.所以项目当中需要对网络请求进行保护,进而保护我们的服务器防止遭到恶意攻击.这就用到了我们的签名.

一、签名的使用范例


下面我们就使用GET请求服务器的方式对比一下有签名和没有签名的区别.

http://192.168.1.150:8080/erp/warehouse?time=2016-05-27
http://192.168.1.150:8080/erp/warehouse?time=2016-05-27&sign=f1d1d072866dcdf015b3edbd99273e21
小结:当我们看到了上面的添加了签名的网络接口,顿时觉得找个接口好复杂.好杂乱.但是因为token字符串是固定的,使用MD5加密不管你怎么搞,签名都是一样的,所以我们要寻找一些可以随意改变的量,那么有什么呢?随机数,时间戳.登录账号.登录密码(这个是万万不可的😂)等等.

二、签名的正确使用姿势


<b>

上面提到我们可以使用一些可变的量进行签名的制作,其实我就称之为要给签名加料,加料加到别人根本不知道签名是如何制作的.下面我就用一张图来说明一下签名的制作和使用过程.
签名加密正确姿势

(1) 从上图我们不难看出签名的制作时需要三个条件的.

token:就是一个字符串,不作为参数,是前端人员和后台人员提前商量好的,记住,是提前商量好的,线下进行的!都知道有这个字符串,直接写在工程中就行.加密解密直接拿来用就行.

(2) 当我们制作好签名之后,我们就要进行网络请求了,然后把网络签名和时间戳作为参数传给后台,后台根据指定的解密工具和制定的解密规则(就是加密规则)进行解密获取里面的信息进行比对,比对成功,就返回对应的数据,比对不成功,也要返回数据,但是返回的是提醒数据,可以提醒用户"签名错误"等等.

三、MD5签名的代码实现


我在ViewController.m中进行签名的制作,以及服务器数据的请求(使用AFNetworking作为网络请求类),我们设定返回的JSON数据有result和msg两个字段,如果result为0则签名对比成功,否则为失败.msg为提示字符串.

//
//  ViewController.m
//  签名技术
//
//  Created by songjc on 16/6/10.
//  Copyright © 2016年 Don9. All rights reserved.
//

#import "ViewController.h"
#import <CommonCrypto/CommonDigest.h>
#import "AFNetworking.h"


@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    //调用网络请求
    [self networkWithData];
}

#pragma mark ---- 网络数据请求 -----

-(void)networkWithData{

    
    AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc]init];
    
    manager.responseSerializer  = [AFHTTPResponseSerializer serializer];
    
    // 设置超时时间
    [manager.requestSerializer willChangeValueForKey:@"timeoutInterval"];
    manager.requestSerializer.timeoutInterval = 10.f;
    [manager.requestSerializer didChangeValueForKey:@"timeoutInterval"];
    
    //生成签名(用字典接受)
    NSDictionary *pkiDic = [self md5String];
    
    NSString *sign = pkiDic[@"PKI"];//签名
    
    NSString *timestamp = pkiDic[@"time"];//时间戳
    
    //设置请求参数(你看 token那个字符串根本就没出现在请求参数当中!!!!)
    NSDictionary *parameters = @{
                                 @"time":@"2016-05-27",
                                 @"sign":sign,
                                 @"timestamp":timestamp
                                 };
    
    
    [manager POST:@"http://192.168.1.150:8080/erp/warehouse" parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        
        if (nil != responseObject) {
            
            NSDictionary *resultDic = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:nil];
            
            if ([resultDic[@"result"]isEqualToString:@"0"]) {
                
                NSLog(@"签名正确!");
                
            }else{
            
            
                NSLog(@"签名不正确!");
            
            }
            
            
        }
        
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        
        NSLog(@"未知错误");
        
    }];

}





#pragma mark-----加密工具以及加密规则-----

- (NSString *)md5:(NSString *)str
{
    const char *cStr = [str UTF8String];
    unsigned char result[16];
    CC_MD5(cStr, strlen(cStr), result); // This is the md5 call
    return [NSString stringWithFormat:
            @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
            result[0], result[1], result[2], result[3],
            result[4], result[5], result[6], result[7],
            result[8], result[9], result[10], result[11],
            result[12], result[13], result[14], result[15]
            ];
}

//加密规则:拼接token和当前时间戳,连续进行三次MD5加密
-(NSDictionary *)md5String
{
    NSString *token = @"DIFJSOYIMVCPAGUI";//token不需要作为参数进行网络传输
    
    //获取当前时间转化Wie时间戳
    NSDate* dat = [NSDate dateWithTimeIntervalSinceNow:0];
    NSTimeInterval a=[dat timeIntervalSince1970]*1000;
    NSString *timeString = [NSString stringWithFormat:@"%0.0f", a];
    
    NSString *md5mystr = [self md5:[NSString stringWithFormat:@"%@%@",token,timeString]];
 
    NSString *md5mystr2 = [self md5:md5mystr];

    NSString *md5mystr3 = [self md5:md5mystr2];

    
    //time为当前的时间戳,PKI为签名字符串
    NSDictionary *md5Dic = @{
                             @"time":timeString,
                             @"PKI":md5mystr3
                             };
    
    
    
    return md5Dic;
}


@end

为了防止上面的代码看的太累,所以我这里吧Demo的地址发给大家.

---->> 点击下载签名相关Demo

签名是一种网络请求安全措施,是我们作为一个前端人员必须的技巧,希望这篇文章能对您有帮助,如果有疑问可以在下方评论,我会及时回复的.谢谢
上一篇下一篇

猜你喜欢

热点阅读