https 后面补充session

由于ios9之后强制的https请求,原来的http请求所占的市场比率也越来越小。在网上查了几十篇类似的https请求的文章,诸如此类的问题很多,但是回答者含糊其辞, 都不尽如人意,经过几天的探索,写下这篇文章,希望可以帮到有这方便需求的开发者。
首先,需要知道什么是https,以此共勉。
1.HTTPS和HTTP的区别

https协议需要到CA申请证书,一般免费证书很少,需要交费。
http是超文本传输协议,信息是明文传输,https则是具有安全性的SSL加密传输协议。
http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。

2.非对称加密算法

  这种加密或许理解起来比较困难,这种加密指的是可以生成公钥和私钥。凡是公钥加密的数据,公钥自身不能解密,而需要私钥才能解密;凡是私钥加密的数据,私钥不能解密,需要公钥才能解密。这种算法事实上有很多,常用的是RSA,其基于的数学原理是两个大素数的乘积很容易算,而拿到这个乘积去算出是哪两个素数相乘就很复杂了,具体原理有兴趣可以自行研究。

非对称加密相比对称加密更加安全,但也存在两个明显缺点:

CPU计算资源消耗非常大。一次完全TLS握手,密钥交换时的非对称解密计算量占整个握手过程的90%以上。而对称加密的计算量只相当于非对称加密的0.1%,如果应用层数据也使用非对称加解密,性能开销太大,无法承受。
非对称加密算法对加密内容的长度有限制,不能超过公钥长度。比如现在常用的公钥长度是2048位,意味着待加密内容不能超过256个字节。

所以公钥加密目前只能用来作密钥交换或者内容签名,不适合用来做应用层传输内容的加解密。
3 身份认证(CA数字证书)

https协议中身份认证的部分是由数字证书来完成的,证书由公钥、证书主体、数字签名等内容组成,在客户端发起SSL请求后,服务端会将数字证书发给客户端,客户端会对证书进行验证,并获取用于秘钥交换的非对称密钥。

数字证书有两个作用:

身份授权。确保浏览器访问的网站是经过CA验证的可信任的网站。
分发公钥。每个数字证书都包含了注册者生成的公钥。在SSL握手时会通过certificate消息传输给客户端。

申请一个受信任的数字证书通常有如下流程:

终端实体(可以是一个终端硬件或者网站)生成公私钥和证书请求。
RA(证书注册及审核机构)检查实体的合法性。如果个人或者小网站,这一步不是必须的。
CA(证书签发机构)签发证书,发送给申请者。
证书更新到repository(负责数字证书及CRL内容存储和分发),终端后续从repository更新证书,查询证书状态等。 

好了,废话不多说,上代码。
首先:如果是双向认证,需要先导入服务器的证书,ASI我不知道怎么做,但是AFN需要新建一个类
- (AFSecurityPolicy*)customSecurityPolicy {

NSString *cerPath = [[NSBundle mainBundle] pathForResource:fuwuqi ofType:];
NSData *certData = [NSData dataWithContentsOfFile:cerPath];
AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
[securityPolicy setAllowInvalidCertificates:YES];
[securityPolicy setPinnedCertificates:@[certData]];
/**** SSL Pinning ****/
return securityPolicy;

} ps:这个类其实建不建都无所谓,但是一定是在请求之前先将这个securityPolicy创建出来

所有的服务器返回的请求都是在- (void)connection:(NSURLConnection *)connection

willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
这个方法中进行验证的,所以需要 重写这个方法

NSString *thePath = [[NSBundle mainBundle] pathForResource:kehuduan ofType:];

NSLog(@"thePath===========%@",thePath);

NSData *PKCS12Data = [[NSData alloc] initWithContentsOfFile:thePath];

CFDataRef inPKCS12Data = (__bridge CFDataRef)PKCS12Data;



SecIdentityRef identity = NULL;

// extract the ideneity from the certificate

[self extractIdentity :inPKCS12Data :&identity];



SecCertificateRef certificate = NULL;

SecIdentityCopyCertificate (identity, &certificate);



const void *certs[] = {certificate};

//                        CFArrayRef certArray = CFArrayCreate(kCFAllocatorDefault, certs, 1, NULL);

// create a credential from the certificate and ideneity, then reply to the challenge with the credential

//NSLog(@"identity=========%@",identity);

NSURLCredential *credential = [NSURLCredential credentialWithIdentity:identity certificates:nil persistence:NSURLCredentialPersistencePermanent];



//           credential = [NSURLCredential credentialWithIdentity:identity certificates:(__bridge NSArray*)certArray persistence:NSURLCredentialPersistencePermanent];



[challenge.sender useCredential:credential forAuthenticationChallenge:challenge];

}

还需要在这个类中添加一个验证客户端的方法OSStatus securityError = errSecSuccess;

CFStringRef password = CFSTR("123456");

const void *keys[] = { kSecImportExportPassphrase };

const void *values[] = { password };



CFDictionaryRef options = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);



CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);

securityError = SecPKCS12Import(inP12Data, options, &items);



if (securityError == 0)

{

    CFDictionaryRef ident = CFArrayGetValueAtIndex(items,0);

    const void *tempIdentity = NULL;

    tempIdentity = CFDictionaryGetValue(ident, kSecImportItemIdentity);

    *identity = (SecIdentityRef)tempIdentity;

}



if (options) {

    CFRelease(options);

}



return securityError;

这样将服务器返回的证书及进行通过公钥解密,与本地的证书进行对比,如果通过则继续下一步,生成一个验证签,携带本地客户端证书发给服务器,服务器进行验证,这就是的双向验证。当然,这里用到的都是自签证书,如果是购买的CA证书,则是不需要验证
securityPolicy那一步的,
欢迎大家点评。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值