nginx与ios实现https双向认证
来源:互联网 发布:杀人漫画剧情知乎 编辑:程序博客网 时间:2024/05/19 09:16
服务端配置
nginx关键配置如下:
listen 443;server_name localhost;ssl on;ssl_certificate /usr/local/opt/nginx/certificates/server.cer;ssl_certificate_key /usr/local/opt/nginx/certificates/server.key.pem;ssl_client_certificate /usr/local/opt/nginx/certificates/ca.cer;ssl_verify_client on;
ssl开启https
ssl_certificate是服务端证书的路径,ssl_certificate_key是服务端私钥的路径ssl_verify_client是配置双向认证(client certificate)
ssl_client_certificate是签发客户端证书的根证书
为什么是根证书,因为可以签发很多客户端证书,只要是由该根证书签发的,服务端都视为认证通过
配置完成以后,一般需要把80端口的http请求跳转到443端口,否则用户可以通过80端口以http方式访问,就失去了安全保护的意义
客户端代码
在网上找了很多ios client certificate的帖子,要么是代码不全,要么是很老的帖子,还是用的NSURLConnection,delegate method都deprecated了,最后找了一个代码片段,改了一下
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil]; NSURL *url = [NSURL URLWithString:@"https://localhost/svc/portal/setting"]; NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];[request setHTTPShouldHandleCookies:NO];[request setTimeoutInterval:30];[request setHTTPMethod:@"GET"]; NSURLSessionDataTask *task = [session dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { NSString *message = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSLog(@"%@", message);}]; [task resume];
上面的代码片段,是用NSURLSessionDataTask发起https请求。在ssl握手阶段,会调用2次下面的delegate method
- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler{ NSString *method = challenge.protectionSpace.authenticationMethod; NSLog(@"%@", method); if([method isEqualToString:NSURLAuthenticationMethodServerTrust]){ NSString *host = challenge.protectionSpace.host; NSLog(@"%@", host); NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]; completionHandler(NSURLSessionAuthChallengeUseCredential, credential); return; } NSString *thePath = [[NSBundle mainBundle] pathForResource:@"client" ofType:@"p12"]; NSData *PKCS12Data = [[NSData alloc] initWithContentsOfFile:thePath]; CFDataRef inPKCS12Data = (CFDataRef)CFBridgingRetain(PKCS12Data); SecIdentityRef identity; // 读取p12证书中的内容 OSStatus result = [self extractP12Data:inPKCS12Data toIdentity:&identity]; if(result != errSecSuccess){ completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil); return; } SecCertificateRef certificate = NULL; SecIdentityCopyCertificate (identity, &certificate); const void *certs[] = {certificate}; CFArrayRef certArray = CFArrayCreate(kCFAllocatorDefault, certs, 1, NULL); NSURLCredential *credential = [NSURLCredential credentialWithIdentity:identity certificates:(NSArray*)CFBridgingRelease(certArray) persistence:NSURLCredentialPersistencePermanent]; completionHandler(NSURLSessionAuthChallengeUseCredential, credential);}-(OSStatus) extractP12Data:(CFDataRef)inP12Data toIdentity:(SecIdentityRef*)identity { OSStatus securityError = errSecSuccess; CFStringRef password = CFSTR("the_password"); 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;}
上面的代码片段,即拷即用,希望能有所帮助。这个方法会被调用2次,第一次是ios app验证server的阶段,第二次是server验证ios app的阶段,即client certificate。关键是每个阶段的校验完成以后,要调用completionHandler方法。网上的大部分帖子都是
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
这行代码是无效的
2 0
- nginx与ios实现https双向认证
- https nginx 双向认证
- Nginx配置https双向认证
- Java nginx https 双向认证
- nginx配置https双向认证
- Nginx配置https双向认证
- Nginx配置https双向认证
- 自签SSL证书实现Nginx配置https双向认证
- nginx+openssl+https 实现双向认证所遇到的坑
- nginx https 双向认证证书创建与配置
- CXF实现HTTPS双向认证
- java https双向认证实现
- java实现https双向认证
- https单向认证与双向认证
- Https单向认证与双向认证
- iOS + Nodejs SSL/Https双向认证
- iOS https 证书双向认证 Afnetworking
- iOS适配HTTPS 双向认证 (AFNetworking)
- PHP之COOKIE支持详解
- 修改listview默认的滑动条
- 第十一周上机项目四类族的设计(2 ) .
- 如何在C语言里面执行SQL语句?
- 12.1.1
- nginx与ios实现https双向认证
- 不同数据库查询
- cocos2d-android学习二 ------cocos2d安装
- 每天进步一点
- com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
- POJ 3133 Manhattan Wiring
- Apple 企业开发者账号&邓白氏码申请记录
- 第十二周 项目一 长颈鹿对动物类的继承(2)
- 互联网实习面试经验