IOS HTTPS证书问题

本文节选自

https://gist.github.com/JacksonTian/5855751


一般而言HTTP和HTTPS都不会遇到这个问题,只要实现NSURLConnectionDataDelegate协议就能完成需求。但是对于自签名证书,NSURLConnection对象无法验证服务端证书的真伪。这个时候需要动用到NSURLConnectionDelegate协议。

具体方法是以下几个:

- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)prote
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge;

其中 canAuthenticateAgainstProtectionSpace如果返回No,将由系统自行处理。返回YES将会由后续的 didReceiveAuthenticationChallenge处理。默认为No。

- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{
    NSLog(@"处理证书");
    return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}
didReceiveAuthenticationChallenge中我们要通过 challengesender告知是否信任服务端的证书。
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
    if (trusted) {
        [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
    } else {
        [challenge.sender cancelAuthenticationChallenge:challenge];
    }
}

我们可以设定trusted来判定是否信任。可以直接设置为YES来表示信任服务端。但是直接设置是不严谨的,并没有验证服务端证书的真伪。

验证证书

在连接建立后,我们可以拿到服务端的证书。要验证它的真伪需要我们用CA的证书来进行判定。

// 获取der格式CA证书路径
NSString *certPath = [[NSBundle mainBundle] pathForResource:@"ca" ofType:@"der"];
// 提取二进制内容
NSData *derCA = [NSData dataWithContentsOfFile:certPath];

// 根据二进制内容提取证书信息
SecCertificateRef caRef = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)derCA);
// 形成钥匙链
NSArray * chain = [NSArray arrayWithObject:(__bridge id)(caRef)];

caChainArrayRef = CFBridgingRetain(chain);

// 取出服务器证书
SecTrustRef trust = [[challenge protectionSpace] serverTrust];

SecTrustResultType trustResult = 0;
// 设置为我们自有的CA证书钥匙连
int err = SecTrustSetAnchorCertificates(trust, caChainArrayRef);
if (err == noErr) {
    // 用CA证书验证服务器证书
    err = SecTrustEvaluate(trust, &trustResult);
}
CFRelease(trust);
// 检查结果
BOOL trusted = (err == noErr) && ((trustResult == kSecTrustResultProceed)||(trustResult == kSecTrustResultConfirm) || (trustResult == kSecTrustResultUnspecified));

UIWebView中访问HTTPS

UIWebView不能处理自签名的证书,需要在它发起访问之前通过上述的方法进行证书的设置判定,之后再通过UIWebView进行访问即可通过。




延伸阅读:

ios下使用rsa算法与php进行加解密通讯

在iOS中创办及使用自签名SSL证书(上)

在iOS中创办及使用自签名SSL证书(下)


iOS: HTTPS 与自签名证书
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值