CocoaHttpServer设置https
客户端向服务器发起需求 ,服务器把证书发给客户端,客户端验证下证书是否合法,然后用证书的数据加密传输数据给服务器,服务器解密
。
使用 OpenSSL 生成自签名证书
上次更新时间: 2021-07-08
OpenSSL 是 SSL 和 TLS 协议的开放式源代码实现。它在标准通信层上提供了传输层安全性,允许其与诸多网络应用程序和服务相结合。
开始之前
需要以下某个角色才能完成此任务:
- 管理员
- 所有者
- 拓扑管理员
- 具有 Settings:Manage 许可权的定制角色
关于此任务
本主题告知您如何使用 OpenSSL 工具箱生成自签名 SSL 证书以启用 HTTPS 连接。
过程
要使用 OpenSSL 生成自签名 SSL 证书,请完成以下步骤:
——————————————————————————————————————————
其他方法的生成证书步骤
// 第一步,为服务器端和客户端准备公钥、私钥 # 生成服务器端私钥 openssl genrsa -out server.key 1024 # 生成服务器端公钥 openssl rsa -in server.key -pubout -out server.pem // 第二步,生成 CA 证书 # 生成 CA 私钥 openssl genrsa -out ca.key 1024 openssl rsa -in ca.key -pubout -out ca.pem # X.509 Certificate Signing Request (CSR) Management. openssl req -new -key ca.key -out ca.csr # X.509 Certificate Data Management. openssl x509 -req -in ca.csr -signkey ca.key -out ca.crt // 第三步,生成服务器端证书 # 服务器端需要向 CA 机构申请签名证书,在申请签名证书之前依然是创建自己的 CSR 文件 openssl req -new -key server.key -out server.csr # 向自己的 CA 机构申请证书,签名过程需要 CA 的证书和私钥参与,最终颁发一个带有 CA 签名的证书 openssl x509 -req -CA ca.crt -CAkey ca.key -CAcreateserial -in server.csr -out server.crt // 第四步,生成cer文件 # 使用openssl 进行转换 openssl x509 -in server.crt -out server.cer -outform der openssl x509 -in ca.crt -out ca.cer -outform der // 将证书导出成浏览器支持的.p12格式,记得导出密码 openssl pkcs12 -export -clcerts -in server.pem -inkey server.key -out server.p12
在第二步时会出来一个填写资料的界面:
Country Name (2 letter code) [AU]:CN State or Province Name (full name) [Some-State]:Guangdong Locality Name (eg, city) []:Shenzhen Organization Name (eg, company) [Internet Widgits Pty Ltd]:cnblogs Organizational Unit Name (eg, section) []:strengthen Common Name (e.g. server FQDN or YOUR name) []:localhost Email Address []:newsagency@163.com
配置服务器
为了方便,我是以mac本地电脑做服务器,使用的是XAMPP搭建的服务器使用的是apache。在其他服务器上应该就是文件路径位置不一样,其他应该是一样的。如果有些服务器没开启ssl,可以网上搜索怎么开启。
修改httpd-ssl.conf文件 把server.crt和server.key的路径修改对就好了 SSLCertificateFile /apache/conf/server.crt SSLCertificateKeyFile /apache/conf/server.key
文件里设置一下开启 https 功能:
- (BOOL)isSecureServer { // Create an HTTPS server (all connections will be secured via SSL/TLS) return YES; } /** * This method is expected to returns an array appropriate for use in kCFStreamSSLCertificates SSL Settings. * It should be an array of SecCertificateRefs except for the first element in the array, which is a SecIdentityRef. **/ - (NSArray *)sslIdentityAndCertificates { SecIdentityRef identityRef = NULL; SecCertificateRef certificateRef = NULL; SecTrustRef trustRef = NULL; NSString *thePath = [[NSBundle mainBundle] pathForResource:@"my" ofType:@"p12"]; NSData *PKCS12Data = [[NSData alloc] initWithContentsOfFile:thePath]; CFDataRef inPKCS12Data = (CFDataRef)CFBridgingRetain(PKCS12Data); CFStringRef password = CFSTR("123"); const void *keys[] = { kSecImportExportPassphrase }; const void *values[] = { password }; CFDictionaryRef optionsDictionary = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL); CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL); OSStatus securityError = errSecSuccess; securityError = SecPKCS12Import(inPKCS12Data, optionsDictionary, &items); if (securityError == 0) { CFDictionaryRef myIdentityAndTrust = CFArrayGetValueAtIndex (items, 0); const void *tempIdentity = NULL; tempIdentity = CFDictionaryGetValue (myIdentityAndTrust, kSecImportItemIdentity); identityRef = (SecIdentityRef)tempIdentity; const void *tempTrust = NULL; tempTrust = CFDictionaryGetValue (myIdentityAndTrust, kSecImportItemTrust); trustRef = (SecTrustRef)tempTrust; } else { NSLog(@"Failed with error code %d",(int)securityError); return nil; } SecIdentityCopyCertificate(identityRef, &certificateRef); NSArray *result = [[NSArray alloc] initWithObjects:(id)CFBridgingRelease(identityRef), (id)CFBridgingRelease(certificateRef), nil]; return result; }
总结一下配置过程中可能碰到配置完成后还是无法访问https的问题:
1、可以判断p12文件是否导入项目,以及路径是否寻找正确
2、确保iOS项目中代码所有的请求都为https请求,因为ssl配置服务器的时候,如果服务器中含有http请求,同样会出现不安全的ssl情况
3、在GCDAsyncSocket.m文件中注释该段代码
// if (value) // { // NSAssert(NO, @"Security option unavailable - kCFStreamSSLLevel" // @" - You must use GCDAsyncSocketSSLProtocolVersionMin & GCDAsyncSocketSSLProtocolVersionMax"); // // [self closeWithError:[self otherError:@"Security option unavailable - kCFStreamSSLLevel"]]; // return; // }
配置AFNetworking
+ (AFSecurityPolicy*)customSecurityPolicy { // /先导入证书 NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"server" ofType:@"cer"];//证书的路径 NSData *certData = [NSData dataWithContentsOfFile:cerPath]; // AFSSLPinningModeCertificate 使用证书验证模式 AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate]; // allowInvalidCertificates 是否允许无效证书(也就是自建的证书),默认为NO // 如果是需要验证自建证书,需要设置为YES securityPolicy.allowInvalidCertificates = YES; //validatesDomainName 是否需要验证域名,默认为YES; //假如证书的域名与你请求的域名不一致,需把该项设置为NO;如设成NO的话,即服务器使用其他可信任机构颁发的证书,也可以建立连接,这个非常危险,建议打开。 //置为NO,主要用于这种情况:客户端请求的是子域名,而证书上的是另外一个域名。因为SSL证书上的域名是独立的,假如证书上注册的域名是www.google.com,那么mail.google.com是无法验证通过的;当然,有钱可以注册通配符的域名*.google.com,但这个还是比较贵的。 //如置为NO,建议自己添加对应域名的校验逻辑。 securityPolicy.validatesDomainName = NO; securityPolicy.pinnedCertificates = @[certData]; return securityPolicy; } + (void)post:(NSString *)url params:(NSDictionary *)params success:(void (^)(id))success failure:(void (^)(NSError *))failure { // 1.获得请求管理者 AFHTTPSessionManager *mgr = [AFHTTPSessionManager manager]; // 2.申明返回的结果是text/html类型 mgr.responseSerializer = [AFHTTPResponseSerializer serializer]; // 加上这行代码,https ssl 验证。 [mgr setSecurityPolicy:[NetworkHelpManager customSecurityPolicy]]; // 3.发送POST请求 [mgr POST:url parameters:params success:^(NSURLSessionDataTask *operation, id responseObj) { if (success) { success(responseObj); } } failure:^(NSURLSessionDataTask *operation, NSError *error) { if (failure) { failure(error); } }]; }
info.plist,配置白名单
<dict> <key>NSAllowsArbitraryLoads</key> <false/> <key>NSExceptionDomains</key> <dict> <key>cer文件中查看</key> <dict> <key>NSExceptionAllowsInsecureHTTPLoads</key> <true/> <key>NSExceptionMinimumTLSVersion</key> <string>TLSv1.0</string> <key>NSExceptionRequiresForwardSecrecy</key> <false/> <key>NSIncludesSubdomains</key> <true/> </dict> </dict> </dict>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
2019-04-02 [CocoaPods]客户端加载第三方库
2019-04-02 [CocoaPods]终端方式加载第三方库
2019-04-02 [CocoaPods]CocoaPods安装详解
2019-04-02 [Swift]LeetCode269. 外星人词典 $ Alien Dictionary
2019-04-02 [Mac]如何让两个窗口各占半个屏幕