最近公司的客户要求,登录请求数据的时候,必须使用他们的域名和自带签名的加密证书,由于之前没有做过,所以自己也研究了一下相关的知识,完成了任务。这篇笔记记录的有两个点:一是HTTPS原理,二是如何在项目快速的配置自带签名证书,完成开发任务。

HTTPS介绍

HTTPS = HTTP + 加密 + 认证 + 完整性保护,也就是说HTTPS是身披SSL外衣的HTTP。

HTTPS常用的加密方式有两种:共享密钥加密(对称加密)和公开密钥加密(非对称加密)。HTTPS采用混合加密机制,也就是两种并用。

共享密钥加密:加密和解密通用一个密钥。优点:加/解密速度快,缺点:一旦密钥泄露了,别人也能够解密数据。

公开密钥加密:加密用公钥,解密用私钥。发送方使用对方的公开密钥进行加密,接收方在使用自己的私有密钥进行解密,就算知道了结果和公钥,破解出被加密的数据是非常难的,一定要使用私钥才能够解密。

HTTPS工作原理图



项目中配置自带签名的证书

建议使用AFNetworking 3.0以上的版本,我目前的是github上面最新的3.2版本。

首先,把客户提供的cer证书添加到项目中,如果不是cer证书,就需要转换成cer格式。



在AFN源码中,有个AFSecurityPolicy.h,可以看到有三个类型:



接下来直接show the code,这是登录的请求方法,post请求。

//:新的邮箱登录
+ (void)Users_loginEmail:(NSString *)aEmail password:(NSString *)aPassword style:(NSString *)style dic:(void (^)(NSDictionary *))adic
{/*
  style
  email    是    string    邮箱
  password    是    string    密码
  */
    NSMutableDictionary *parameters = [NSMutableDictionary dictionaryWithObjects:@[aEmail,aPassword,style] forKeys:@[@"email",@"password",@"style"]];
    NSString * listUrl = [NSString stringWithFormat:@"Index/index"];
    [self POSTSetTheURL:listUrl parameters:parameters token:@"否" Details:^(NSDictionary *dic)
    {
        adic(dic);
    }];
}

//POST设置根URL和传入参数
+(void )POSTSetTheURL:(NSString *)aUrl parameters:(NSMutableDictionary * )Aparameters token:(NSString * )aToken  Details:(void(^)(NSDictionary *dic))adic{
    NSString *listUrl;
    if ([aUrl containsString:@"?"]) {
        listUrl =[NSString stringWithFormat:@"%@%@",URLSERVER_TRAINING,aUrl];
    }else{
        listUrl =[NSString stringWithFormat:@"%@%@",URLSERVER_TRAINING,aUrl];
    }
    
    if ([aToken isEqualToString:@"是"]) {
            [Aparameters setObject:[app.userDefaults objectForKey:TOKENKEY_DATA] forKey:@"token"];
            [Aparameters setObject:[app.userDefaults objectForKey:EXPIRES_TOKENKEY] forKey:@"secret_key"];
    }

    NSLog(@"%@",listUrl);
    
    /*
    这里就是配置的代码
    AFSecurityPolicy *policy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
    AFHTTPSessionManager *manager = [[AFHTTPSessionManager manager] initWithBaseURL:[NSURL URLWithString:listUrl]];
    manager.securityPolicy = policy;
    manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    这里就是配置的代码
    */
    
    [manager POST:listUrl parameters:Aparameters progress:^(NSProgress * _Nonnull uploadProgress) {
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        NSString *data = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
        NSDictionary *dic = [NSString dictionaryWithJsonString:data];
        adic(dic);
        NSString *strCode =[NSString stringWithFormat:@"%@",dic[@"code"]];
        if ([strCode isEqualToString:@"1033"]) {
            [[NSNotificationCenter defaultCenter] postNotificationName:@"getExpiredRelogin" object:nil];
        }
        
        if ([dic[@"status"] isEqualToString:@"error"]){//判断是否要重新登录和重新请求tokenKey
            [app.HUD Hide_Show:YES];//YES 是隐藏的意思 ,NO是显示的意思
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            NSLog(@"Error: %@", error);
            if (error.code != -999) {
                NSMutableDictionary *parameters= [NSMutableDictionary
                                                  dictionaryWithObjects:@[@"error"]
                                                  forKeys:@[@"code"]];
                adic(parameters);
                [app.HUD Hide_Show:YES];//YES 是隐藏的意思 ,NO是显示的意思
                [MyToast showWithText:[NSString stringWithFormat:@"似乎已断开与互联网的连接"]];
            }
    }];
}

复制代码

最重要的就是这几句:选择AFSSLPinningModeCertificate,然后还有一个注意点就是,使用自带签名证书,AFHTTPSessionManager创建时,必须是initWithBaseURL,不然就会报错,如下面的截图:

AFSecurityPolicy *policy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
    AFHTTPSessionManager *manager = [[AFHTTPSessionManager manager] initWithBaseURL:[NSURL URLWithString:listUrl]];
    manager.securityPolicy = policy;
    manager.responseSerializer = [AFHTTPResponseSerializer serializer];
复制代码



如果证书验证通过,如下图所示,return YES,表示证书验证通过。



总结

希望在掘金平台自己能够分享,多跟各路大神交流,我也是在不断学习中,希望自己的技术能够越来越好。