最近公司的客户要求,登录请求数据的时候,必须使用他们的域名和自带签名的加密证书,由于之前没有做过,所以自己也研究了一下相关的知识,完成了任务。这篇笔记记录的有两个点:一是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,表示证书验证通过。
总结
希望在掘金平台自己能够分享,多跟各路大神交流,我也是在不断学习中,希望自己的技术能够越来越好。