iOS上访问HTTPS站点几种方法优缺点

下面简单分享一下,希望各位提点意见:

1。调用私有API
    最简单,也最危险的方法,调用 setAllowsAnyHTTPSCertificate:forHost  ,后果怎么样就不用我说了吧。

2.  libCurl
   这是一个开源项目,用C语言写的URL转换库,是基于于openssl的,可以支持目前大部分的URL,包括DICT, FILE, FTP, FTPS, GOPHER, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, TELNET 和 TFTP,而且用这个不会使用苹果禁止的私有API,所以可以顺利通过App Store的审核。 但是有一个问题,就是要自己编译libcurl和openssl 的两个静态库,其中的配置比较麻烦,不熟悉在unix环境下编译静态库的朋友们可能就会皱眉头了。这有两个链接,可以参考 :

http://www.therareair.com/2009/01/01/tutorial-how-to-compile-openssl-for-the-iphone/
http://www.yifeiyang.net/iphone-web-development-skills-of-the-article-5-https-server-using-libcurl-to-connect/

编译成功后,将libcurl引入工程,再加上下面这些代码,就可以顺利访问HTTPS站点了

/***************  调用libcurl 访问HTTPS站点 ****************
    const char *urlstring=[homeUrl cStringUsingEncoding:NSUTF8StringEncoding];
    CURL *curl;
    CURLcode res;
    char*  buffer;
    int    buflen=1024;
    size_t*    n;
    curl = curl_easy_init();
    if (curl) {
        curl_easy_setopt(curl, CURLOPT_URL, "https://10.20.7.236/login.aspx?ReturnUrl=%2f");
        //curl_easy_setopt(curl, CURLOPT_URL, urlstring);
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
        
        res = curl_easy_perform(curl);
        
        if (0 != res) {
            fprintf(stderr, "curl error: %d\n", res);
        }
        //res=curl_easy_recv(curl, buffer, buflen, n);
        //printf("%s",buffer);
        curl_easy_cleanup(curl);
    }
  *****************************************************/
通过联机调试在我的ipod上成功的访问到了HTTPS站点,在控制台中可以看到网页的内容,剩下的就是如何把这些内容存到一个字符数组里面,再通过调用UIwebView的loadHTMLString方法,就可以显示内容了,  不过最后这一步我还没有找到方法,希望有兴趣的朋友可以帮我解决这个问题。


3。ASIHTTPRequest 
    这个开源项目也是流行很久了, 但是一般都是用来替代NSURLConnection,其实里面的功能还是挺强大的,只是对于HTTPS访问这一块我有点不太满意,
  里面有一个方法,是可以直接忽略证书验证的, 

  disabling secure certificate validation

You may wish to use this for testing purposes if you have a self-signed secure certificate. I recommend purchasing a certificate from a trusted certificate authority and leaving certificate validation turned on for production applications.

[request setValidatesSecureCertificate:NO];

但是这样做有一点危险,如果是放在企业环境里部署的话,那外面的人都可以访问内部的网站了,SSL这一层就形同虚设。所以我又找了一下,发现他还有另一个方法,可以设置客户端的证书:

Client certificates support
If your server requires the use of client certificates, as of v1.8 it is now possible to send them with your request.

// Will send the certificate attached to the identity (identity is a SecIdentityRef)
[request setClientCertificateIdentity:identity];

// Add an additional certificate (where cert is a SecCertificateRef)
[request setClientCertificates:[NSArray arrayWithObject:(id)cert]];
There is a helper function in 'ClientCertificateTests.m' in the iPhone / iPad sample app that can create a SecIdentityRef from PKCS12 data (this function only works on iOS).

这个方法需要把p12文件放进工程里面,然后调用[ClientCertificateTest extractIdentity:&identity andTrust:&trust fromPKCS12Data:PKCS12Data]; 来获取identity
,这个方法是这样的  
+ (BOOL)extractIdentity:(SecIdentityRef *)outIdentity andTrust:(SecTrustRef*)outTrust fromPKCS12Data:(NSData *)inPKCS12Data
{
    OSStatus securityError = errSecSuccess;
    
    NSDictionary *optionsDictionary = [NSDictionary dictionaryWithObject:@"" forKey:(id)kSecImportExportPassphrase];
    
    CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
    securityError = SecPKCS12Import((CFDataRef)inPKCS12Data,(CFDictionaryRef)optionsDictionary,&items);
    
    if (securityError == 0) { 
        CFDictionaryRef myIdentityAndTrust = CFArrayGetValueAtIndex (items, 0);
        const void *tempIdentity = NULL;
        tempIdentity = CFDictionaryGetValue (myIdentityAndTrust, kSecImportItemIdentity);
        *outIdentity = (SecIdentityRef)tempIdentity;
        const void *tempTrust = NULL;
        tempTrust = CFDictionaryGetValue (myIdentityAndTrust, kSecImportItemTrust);
        *outTrust = (SecTrustRef)tempTrust;
    } else {
        NSLog(@"Failed with error code %d",(int)securityError);
        return NO;
    }
    return YES;
}
这个方法需要引用到Security.framework这个框架(我第一次没有引用,结果报错,我想官方的东西怎么还有错呢,郁闷了好久才发现是这个框架没有引用,晕死)。之后应该就是通过[ASIHTTPRequest startSynchronous] 可以访问HTTPS网站了。  为什么说是应该呢? 因为我也没有试出来,呵呵 ```可能是证书的问题,我在extractIdentity:&identity andTrust:&trust fromPKCS12Data:PKCS12Data 这个方法里获取到的securityError 为-26275 ,在网上找了半天也没找出个结果来,所以也只能暂时搁置了。


-(void) viewHomePage{
    NSURL *url=[NSURL URLWithString:homeUrl];
    
    NSBundle *bundle = [NSBundle mainBundle]; //取得mainBundle
    NSString *plistPath = [bundle pathForResource:@"Root" ofType:@"plist"]; //取得文件路径
    // 或可以写成
    // NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"文件名" ofType:@"plist"];
    //读取到一个NSDictionary
    NSArray  *array=[[NSArray alloc]initWithContentsOfFile:plistPath];
    
    NSDictionary *dictionary = [array objectAtIndex:1];
    NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
    [defaults registerDefaults:dictionary];
    
    BOOL needAuthentication=[defaults boolForKey:@"needAuth"];
    
    SecIdentityRef identity = NULL;
    SecTrustRef trust = NULL;
    NSData *PKCS12Data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"ioa.bingosoft.net" ofType:@"pfx"]];
    [SenchaShellViewController extractIdentity:&identity andTrust:&trust fromPKCS12Data:PKCS12Data];
    
    //******************   调用 ASIHTTPRequest 访问HTTPS站点  ****************
    ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
    
    [request setClientCertificateIdentity:identity];
    //[request setValidatesSecureCertificate:NO];
    //[request startSynchronous];
    [request setValidatesSecureCertificate:needAuthentication];
    [request startSynchronous];
    
    NSError *error = [request error];
    if (!error) {
        [self.viewer loadHTMLString:[request responseString] baseURL: [request url]];
    }
    else {
        NSLog(@"Error: %@", error );
    }


4。 官方API
   最后一个是官方的API, 按理说这个应该放到最前面,因为是官方的嘛,但是实际上我一次都没有试成功过,所以有点怀疑他的真实性,不过也许有人成功了,所以也拿上来讨论一下。
简单来说通过NSurlconnection的这两个委托方法来忽略认证,关于Certificate Authentication是有官方文档的,但是官方文档太长了,我没有心思看完,所以还没有深入研究下去。
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
    return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
        //if ([trustedHosts containsObject:challenge.protectionSpace.host])
            [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] 
                 forAuthenticationChallenge:challenge];
    
    [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值