ios https访问自建证书时遇到的问题

来源:互联网 发布:2017全明星赛哈登数据 编辑:程序博客网 时间:2024/05/29 04:15

网上找到方法把证书加到bundle reosource里面:


然后使用下面的代码验证证书:

- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {    return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];}- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge{//     直接验证服务器是否被认证(serverTrust),这种方式直接忽略证书验证,直接建立连接,但不能过滤其它URL连接,可以理解为一种折衷的处理方式,实际上并不安全,因此不推荐。//     SecTrustRef serverTrust = [[challenge protectionSpace] serverTrust];//     return [[challenge sender] useCredential: [NSURLCredential credentialForTrust: serverTrust]//     forAuthenticationChallenge: challenge];    if ([[[challenge protectionSpace] authenticationMethod] isEqualToString: NSURLAuthenticationMethodServerTrust]) {        do            {            SecTrustRef serverTrust = [[challenge protectionSpace] serverTrust];            NSCAssert(serverTrust != nil, @"serverTrust is nil");            if(nil == serverTrust)                break; /* failed */            /**             *  导入多张CA证书(Certification Authority,支持SSL证书以及自签名的CA)             */            NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"xxx" ofType:@"der"];//自签名证书            NSData *caCert = [NSData dataWithContentsOfFile:cerPath];//            NSString *cerPath2 = [[NSBundle mainBundle] pathForResource:@"apple" ofType:@"cer"];//SSL证书//            NSData *caCert2 = [NSData dataWithContentsOfFile:cerPath2];            if(nil == caCert)                break; /* failed */            SecCertificateRef caRef = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)caCert);            if(nil == caRef)                break; /* failed */            NSArray *caArray = @[(__bridge id)(caRef)];            if(nil == caArray)                break; /* failed */            OSStatus status = SecTrustSetAnchorCertificates(serverTrust, (__bridge CFArrayRef)caArray);            SecTrustSetAnchorCertificatesOnly(serverTrust,false);            if(!(errSecSuccess == status))                break; /* failed */            SecTrustResultType result = -1;            status = SecTrustEvaluate(serverTrust, &result);            if(!(errSecSuccess == status))                break; /* failed */            NSLog(@"stutas:%d",(int)status);            NSLog(@"Result: %d", result);            BOOL allowConnect = (result == kSecTrustResultUnspecified) || (result == kSecTrustResultProceed);            if (allowConnect) {                NSLog(@"success");            }else {                NSLog(@"error");            }            if(!allowConnect)                {                break; /* failed */                }#if 0            /* Treat kSecTrustResultConfirm and kSecTrustResultRecoverableTrustFailure as success */            /*   since the user will likely tap-through to see the dancing bunnies */            if(result == kSecTrustResultDeny || result == kSecTrustResultFatalTrustFailure || result == kSecTrustResultOtherError)                {                break; /* failed to trust cert (good in this case) */                }#endif                // The only good exit point            return [[challenge sender] useCredential: [NSURLCredential credentialForTrust: serverTrust]                          forAuthenticationChallenge: challenge];                        } while(0);    }    return [[challenge sender] cancelAuthenticationChallenge: challenge];}

有个问题就是不能使用.cer的证书,否则SecCertificateCreateWithData会返回nil,我就是被这个坑了两天。。。

原因是:The newly created certificate object. Call the CFRelease function to release this object when you are finished with it. Returns NULL if the data passed in the data parameter is not a valid DER-encoded X.509 certificate.

可以使用:

openssl x509 -in xxx.cer -outform der -out xxx.der来转

这是我参考的文章:http://www.jianshu.com/p/6b9c8bd5005a

1 0