`
bewithme
  • 浏览: 430722 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

UIWebView实现https双向认证请求

阅读更多

 

        什么是HTTPS双向认证我已在先前的博文 ASIHTTPRequest实现https双向认证请求

中有讲述,不理解的读者可以先复习一下。本文是用UIWebView来实现对需要客户端证书验证的服务请求,网上有些文章中有涉及到此内容,但都只言片语,没有讲完全,更没有完整的代码,让人困扰不已。但是此知识点其实还是比较重要并且是有一定难度的,在安全性要求比较高的场合比如银行APP中应该比较常用,当然你也可以用在你自己的项目中,为您的应用增加安全保护。

      

        废话我就少说点了,来看看关键代码吧。

 

    

@interface RootViewController : UIViewController<UIWebViewDelegate,NSURLConnectionDelegate>
{
    UIWebView *webView;
    
    UIActivityIndicatorView *activityIndicatorView;
    
    //当前的url
    NSURL *_currenURL;
    NSURLConnection* reUrlConnection;//重发请求
    NSURLRequest* originRequest;

}

@property(nonatomic,assign,getter =isAuthed)BOOL authed;
@property(nonatomic,strong)NSURL *currenURL;

@end

 

   以上代码是UIWebView的视图控制器的声明代码,实现以下两个代理UIWebViewDelegate,NSURLConnectionDelegate

 

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
    
    NSString *url=[[request URL]absoluteString];
    
    if ([url hasPrefix:@"protocol://"]) {
        UIAlertView* alert=[[UIAlertView alloc]initWithTitle:@"Called by JavaScript"
                                                     message:@"You've called iPhone provided control from javascript!!" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:nil];
        [alert show];
      
        return NO;
    }
    
    NSString* scheme = [[request URL] scheme];
    NSLog(@"scheme = %@",scheme);
    //判断是不是https
    if ([scheme isEqualToString:@"https"]) {
        //如果是https:的话,那么就用NSURLConnection来重发请求。从而在请求的过程当中吧要请求的URL做信任处理。
        if (!self.isAuthed) {
            originRequest = request;
            NSURLConnection* conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
            [conn start];
            [webView stopLoading];
            return NO;
        }
    }
    return YES;
}

 以上代码重载了UIWebViewDelegate中的shouldStartLoadWithRequest 方法。

 

- (void)connection: (NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
    
    if ([challenge previousFailureCount]== 0) {
        _authed = YES;
        NSString *path = [[NSBundle mainBundle]pathForResource:@"wenfeng.xu" ofType:@"pfx"];
        NSData *p12data = [NSData dataWithContentsOfFile:path];
        
        CFDataRef inP12data = (__bridge CFDataRef)p12data;
        
        SecIdentityRef myIdentity;
        SecTrustRef myTrust;
        extractIdentityAndTrust(inP12data, &myIdentity, &myTrust);
        long count = SecTrustGetCertificateCount(myTrust);
        NSMutableArray* myCertificates = nil;
        if(count > 1) {
            myCertificates = [NSMutableArray arrayWithCapacity:count];
            for(int i = 1; i < count; ++i) {
                [myCertificates addObject:(__bridge id)SecTrustGetCertificateAtIndex(myTrust, i)];
            }
        }
        
        NSURLCredential *credential = [NSURLCredential credentialWithIdentity:myIdentity certificates:nil persistence:NSURLCredentialPersistenceNone];
        
        assert(credential != nil);
        
        NSLog(@"User: %@, certificates %@ identity:%@", [credential user], [credential certificates], [credential identity]);
        [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
        
    }else{
        [challenge.sender cancelAuthenticationChallenge:challenge];
    }
}

 

  NSString *path = [[NSBundle mainBundle]pathForResource:@"wenfeng.xu" ofType:@"pfx"];

   以上代码声明客户端证书的类型与名称

  

OSStatus extractIdentityAndTrust(CFDataRef inP12data, SecIdentityRef *identity, SecTrustRef *trust)
{
    OSStatus securityError = errSecSuccess;
    
    CFStringRef password = CFSTR("p@ssw0rd888");
    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 myIdentityAndTrust = CFArrayGetValueAtIndex(items, 0);
        const void *tempIdentity = NULL;
        tempIdentity = CFDictionaryGetValue(myIdentityAndTrust, kSecImportItemIdentity);
        *identity = (SecIdentityRef)tempIdentity;
        const void *tempTrust = NULL;
        tempTrust = CFDictionaryGetValue(myIdentityAndTrust, kSecImportItemTrust);
        *trust = (SecTrustRef)tempTrust;
        
        CFIndex count = CFArrayGetCount(items);
        NSLog(@"Certificates found: %ld",count);
    }
    
    if (options) {
        CFRelease(options);
    }
    
    return securityError;
}

  以上代码实现请求前公钥与私钥的提取

  

CFStringRef password = CFSTR("p@ssw0rd888");

 以上代码声明证书的访问密码

 

      完整的代码已在附件中,支持自签名的服务器证书,有任何问题请联系qq 359709421

 

如果您觉得我的文章给了您帮助,请为我买一杯饮料吧!以下是我的支付宝,意思一下我将非常感激!

 

 

 

 

     

分享到:
评论

相关推荐

    ios-HTTPS双向认证.zip

    实现HTTPS的双向认证,防止MITM(中间人攻击),示例展示了AFNetworking的推荐使用方式、双向认证、UIWebView的双向认证、密码强度检测,最新代码请移步:https://github.com/iFindTA/NHCerSecurityPro

    UIWebView实现图文混排

    当需要在应用中实现图文混排时,UIWebView是一个非常实用的选择,因为它能够轻松地将文字和图片结合在一起显示。本篇文章将详细探讨如何利用UIWebView来实现这一功能。 首先,我们需要理解图文混排的基本概念。图文...

    [转] 为UIWebView实现离线浏览

    这篇博客(原文链接:https://re-reference.iteye.com/blog/1391408)主要介绍了如何利用缓存机制来实现在iOS应用中UIWebView的离线浏览。通过预先下载并存储网页内容,当网络不可用时,UIWebView可以从本地缓存中...

    UIWebView被WKWebView替换后在iOS12(不包含12)以下https双向认证失败的解决历程总结

    在日版iPhone5,10.3.3 系统上,有一些遗留问题,先不管了 ...在UIWebView时代,UIWebView的delegate没有处理双向认证的方法,需要在shouldStartLoadWithRequest方法中将请求拦截使用NSURLConnectio

    IOS自定义请求uiwebview的loading框

    本文将详细介绍如何在iOS应用中自定义UIWebView的loading框,实现文字和转圈特效的动态显示,并确保调用方便。 首先,我们来看一下`LoadingView.h`头文件。在这个文件中,通常会声明一个名为`LoadingView`的自定义...

    NSURLCache让本地数据来代替远程UIWebView请求

    3. 监听缓存行为:虽然`UIWebView`默认会处理`NSURLCache`,但我们可以通过实现`UIWebViewDelegate`中的`webView(_:didReceiveResponse:)`方法,来获取关于是否使用了缓存的信息。 ```swift func webView(_ webView:...

    UIWebViewDemo

    3. **处理导航**: `UIWebView`提供了一些导航相关的代理方法,如`webView(_:shouldStartLoadWith:)`,可以用来决定是否开始加载请求,以及`webViewDidFinishLoad(_:)`,表示网页加载完成。 4. **返回上页功能**: 要...

    iphone 利用本地数据来代替远程UIWebView请求实例

    总结来说,这个实例展示了如何通过自定义NSURLCache来实现iPhone应用中UIWebView利用本地数据代替远程请求的功能。通过这种方式,我们可以提升应用的响应速度,减少对网络的依赖,提高用户体验。同时,这也是一种...

    网页视图 UIWebView

    总结起来,UIWebView是iOS开发中的一个重要组件,它允许我们在应用程序内嵌入网页内容,通过处理URL字符串、利用其属性和协议,可以实现丰富的交互功能。尽管有新的替代品,但理解UIWebView的工作原理和使用方式对于...

    UIWebView原生与H5交互

    1. `UIWebViewDelegate`协议:通过实现`webView:shouldStartLoadWithRequest:navigationType:`方法,我们可以监听到`UIWebView`加载URL的请求,包括JavaScript发起的URL请求。当JavaScript执行`window.location.href...

    UIWebView使用

    UIWebView提供了与JavaScript代码交互的能力,这主要通过`stringByEvaluatingJavaScriptFromString:`方法实现。你可以执行任何有效的JavaScript代码,并获取其返回值(如果有的话)。 ```swift let jsCode = ...

    UIWebView和js交互

    在iOS开发中,UIWebView是苹果提供的一种原生控件,用于展示网页内容。它可以加载HTML、CSS和JavaScript代码,并且支持与JavaScript进行交互,从而实现原生应用和Web内容的融合。本教程将深入探讨UIWebView与...

    IOS UIWebView Demo

    这个Demo可能包含了创建UIWebView对象、加载URL、处理用户交互以及与JavaScript交互等功能的实现。 【标签】:“IOS UIWebView Demo”标签明确了讨论的主题,即与iOS平台相关的UIWebView组件的使用示例。 【文件...

    iPhone开发之UIWebView示例程序

    在iOS应用开发中,UIWebView是一个非常重要的组件,它允许开发者在应用程序内嵌入网页内容,实现网页浏览功能。这个示例程序是针对iPhone平台,旨在帮助开发者理解如何有效地使用UIWebView来展示网页数据。通过这个...

    UIWebView与 javascript的交互

    这个"UIWebView与javascript的交互"的标题暗示了我们正在探讨如何在iOS应用中利用UIWebView与嵌入的HTML页面进行双向通信,即通过Objective-C/Swift代码与JavaScript代码相互调用。这种交互能力使得开发者可以充分...

    UIWebView的使用代码

    UIWebView包含一个scrollView组件,用来将关联web内容实现滚动效果,页面滚动后的UIWebView的面板周围会出现阴影效果,该效果是在四周添加UIImageView实现的,因此移除这种阴影效果的代码如下: ? 1 2 3 4 5 ...

    UIWebView和js交互demo1

    本项目"UIWebView和js交互demo1"就是展示了如何利用UIWebView进行 OC与JS之间的通信,实现两者之间的数据交换和功能调用。 一、UIWebView基本使用 UIWebView的使用主要包括初始化、加载网页内容以及设置代理。首先...

    UIWebView与JS交互小例子

    本示例将深入探讨如何通过UIWebView实现App与JS的双向通信。 一、APP向JS提交信息 在iOS应用中,我们可以通过`UIWebView`的`stringByEvaluatingJavaScriptFromString:`方法来执行JavaScript代码,从而将数据传递给...

Global site tag (gtag.js) - Google Analytics