服务端配置

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是签发客户端证书的根证书

为什么是根证书。由于能够签发非常多client证书,仅仅要是由该根证书签发的,服务端都视为认证通过

配置完毕以后,一般须要把80port的http请求跳转到443port,否则用户能够通过80port以http方式訪问,就失去了安全保护的意义

client代码

在网上找了非常多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];

这行代码是无效的

nginx与ios实现https双向认证的更多相关文章

  1. HTTPS 双向认证构建移动设备安全体系

    HTTPS 双向认证构建移动设备安全体系 对于一些高安全性要求的企业内项目,我们有时希望能够对客户端进行验证.这个时候我们可以使用Https的双向认证机制来实现这个功能. 单向认证:保证server是 ...

  2. Tomcat 配置 HTTPS双向认证

    Tomcat 配置 HTTPS 双向认证指引说明: � 本文档仅提供 Linux 操作系统下的指引 � 在阅读本指引前请您在 Linux 部署 JDK 和 Tomcatserver为了 Tomcat ...

  3. httpd设置HTTPS双向认证

    去年用tomcat.jboss配置过HTTPS双向认证,那时候主要用的是JDK自带的keytool工具.这次是用httpd + openssl,区别比较大 在网上搜索了很多文章,发现全面介绍的不多,或 ...

  4. Https双向认证Android客户端配置

    Https .cer证书转换为BKS证书 公式https://blog.csdn.net/zww986736788/article/details/81708967 keytool -importce ...

  5. Android Https双向认证 + GRPC

    keywords:android https 双向认证android GRPC https 双向认证 ManagedChannel channel = OkHttpChannelBuilder.for ...

  6. 双向认证 HTTPS双向认证

    [微信支付]微信小程序支付开发者文档 https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=4_3 HTTPS双向认证使用说明 ...

  7. https双向认证訪问管理后台,採用USBKEY进行系统訪问的身份鉴别,KEY的证书长度大于128位,使用USBKEY登录

    近期项目需求,须要实现用USBKEY识别用户登录,採用https双向认证訪问管理后台管理界面,期间碰到过一些小问题,写出来给大家參考下. 1:前期准备工作 USBKEY 硬件:我买的是飞天诚信 epa ...

  8. nodejs之https双向认证

    说在前面 之前我们总结了https的相关知识,如果不懂可以看我另一篇文章:白话理解https 有关证书生成可以参考:自签证书生成 正题 今天使用nodejs来实现https双向认证 话不多说,直接进入 ...

  9. SpringBoot服务间使用自签名证书实现https双向认证

    SpringBoot服务间使用自签名证书实现https双向认证 以服务server-one和server-two之间使用RestTemplate以https调用为例 一.生成密钥 需要生成server ...

随机推荐

  1. Kotlin Vertx

    Kotlin & Vertx Kotlin 是一门好语言,值得大家了解一下. Vertx 是一个好框架,也值得大家了解一下. Kotlin 写过js,也写过一点点go,主力一直是java.用了 ...

  2. 21. 无法执行该操作,因为链接服务器”Server_202”的 OLE DB 访问接口 “SQLNCLI10″ 无法启动分布式事务”

    无法执行该操作,因为链接服务器”Server_202”的 OLE DB 访问接口 “SQLNCLI10″ 无法启动分布式事务” 原因:调用存储过程的方式有问题,必须用JDBC方式调用存储过程才可以正常 ...

  3. jQuery 之 $.get、$.post、$.getJSON、$.ajax

    对 JSTL标签 加以巩固,同时在自己的博客中与之分享: http://app.yinxiang.com/shard/s20/sh/76feadb0-957a-40bc-895d-4d28025ce2 ...

  4. Win32中安全的子类化(翻译)

    关于子类化的话题虽然有些旧,但它至今仍然不失为一种开发Windows的强有力技术,在MFC的内核.甚至.NET的内核中都离不开它,希望本连载能对Windows开发的爱好者有所帮助. 原文标题:Safe ...

  5. 一个基于MINA框架应用的最简单例子

    直接上代码.关于原理和主要的API以后在说.先能跑通了在说. 主要的包:mina-core-2.0.0.jar[到官网上下载完整项目包里面还有文档和依赖包],jcl-over-slf4j-1.5.11 ...

  6. Siverlight+WCF+Nhibernate 开发之旅(一)

    最近正在开发sl程序,考虑了很久,参考了一些框架,令人头疼的数据访问层最终选择wcf+nhibernate,至于为什么选择wcf和nh,个人参考了其他的框架感觉这两者结合从开发效率和便捷性方面比其他的 ...

  7. sshuttle基于VPN的透明代理,安全连接

    sshuttle基于VPN的透明代理, 通过 ssh 创建一条从你电脑连接到任何远程服务器的 VPN 连 sudo sshuttle -r username@sshserver 0.0.0.0/0 - ...

  8. DRP总结

    DRP终于结束了,战线有点长了.记得刚开始听说DRP的时候,感觉这个名词很专业,再加上视频一共有300集,顿时感觉这是一个大项目,很正规.很专业的项目.虽然后来知道DRP知识ERP的一个分支,项目规模 ...

  9. 给Object扩展新方法

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  10. python-操作exel(xlrd,xlwt)

    1.使用第三方库 python中处理excel表格,常用的库有xlrd(读excel)表.xlwt(写excel)表.openpyxl(可读写excel表)等. xlrd读数据较大的excel表时效率 ...