服务端配置
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];
这行代码是无效的
分享到:
相关推荐
Windows下Nginx配置SSL实现Https访问(包含证书生成)
docker构建nginx双向认证https服务器。 openssl命令生成双向认证自签名证书。 nginx配置https(tls)服务。 浏览器访问服务器需要导入客户端证书到浏览器中。
主要介绍了详解Nginx SSL快速双向认证配置(脚本),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
linux nginx双向认证服务搭建tomcat ssl 步骤
主要介绍了使用Nginx实现HTTPS双向验证的方法,涉及到单向验证和双向验证的区别介绍,本文介绍的非常详细,具有参考借鉴价值,感兴趣的朋友一起学习吧
实现nginx双活+双向SSL认证+高并发+安全加固+会话共享+主被动健康探测部署
自己搭建的,nginx端实现https访问
本资源是一个 CentOS 下对 Nginx + Tomcat 配置 SSL 实现服务器 / 客户端双向认证配置示例。详细如何配置请参考博客《图文:CentOS 下对 Nginx + Tomcat 配置 SSL 实现服务器 / 客户端双向认证》,地址是:...
Nginx配置http转https以及https访问http静态资源.docx
主要给大家介绍了关于nginx配置ssl实现https访问的相关资料,这个教程非常适合新手小白,文中通过示例代码将实现的方法一步步介绍的非常详细,需要的朋友可以参考借鉴,下面来一起看看吧
主要介绍了详解Nginx服务器和iOS的HTTPS安全通信的相关资料,需要的朋友可以参考下
详细介绍python+django+nginx+uwsgi配置过程,1. Apache: 世界使用排名第一的Web服务器 2. Nginx: 轻量级的Web服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器 3. nginx 做为代理服务器:负责静态资源...
nginx配置+https
nginx图片服务器配置和https配置
现在的网站支持Https几乎是标配功能,Nginx能很好的支持Https功能。下面列举一个配置同时支持Http和Https的功能。 需要注意的是:既然选择使用Https,就是为了保证通信安全,那么就没必要再用Http进行通信了。在URL...
(最近安排的ssl改造工作任务重时间短,经过翻阅了大量网文,以及自己亲手搭建虚拟机测试到最后现场测试再验收。在此个人总结成了这一文档,如下载后别乱转 谢谢) (本手册适用于运维人员需要...nginx的安装以及配置