带有 SSL 和证书的 iPhoneHTTPServer

Posted

技术标签:

【中文标题】带有 SSL 和证书的 iPhoneHTTPServer【英文标题】:iPhoneHTTPServer with SSL and certificate 【发布时间】:2014-08-21 09:13:23 【问题描述】:

我在我的项目中使用 iPhoneHTTPServer 示例来使用 HTTPServer,并使用 .ipa 托管一个 .plist 文件来模拟临时部署。

您可能知道,从 ios7 开始,托管文件的服务器必须受到保护,因此我尝试使用 SSL 身份验证,但失败了。

首先,服务器似乎可以正确启动,但是当我尝试像这样访问我的服务器时它失败了:

NSURL *plistUrl = [NSURL URLWithString:@"itms-services://?action=download-manifest&url=https://localhost:8080/TestMAJ2.plist"];
[[UIApplication sharedApplication] openURL:plistUrl];

我有这个错误:

NSAssert(NO, @"Security option unavailable - kCFStreamSSLLevel" @" - You must use GCDAsyncSocketSSLProtocolVersionMin & GCDAsyncSocketSSLProtocolVersionMax");

如何绕过此错误?我试图删除 TLS 设置的 kCFStreamSSLLevel(为什么不?^^),但连接仍然无法正常工作,我有一个弹出窗口“无法连接到本地主机”或类似的东西......

关于 SSL 身份验证,示例中的 DDKeychain 类不好,因为它是 Mac 的 API,所以我使用此代码:How to make iPhoneHTTPServer secure server,证书来自 Keychain Access,它是我用于签署我的证书的证书应用程序。也许它不是正确的证书?还是正确的代码?你知道在 iOS 中使用 SecureHTTPServer 的一个非常简单的例子吗?

【问题讨论】:

没人能解决我的问题吗? 使用[sslSettings setObject:[NSNumber numberWithInteger:2] forKey:GCDAsyncSocketSSLProtocolVersionMin]; [sslSettings setObject:[NSNumber numberWithInteger:2] forKey:GCDAsyncSocketSSLProtocolVersionMax]; 绕过这个错误。基本上这会将 TLS 版本设置为 2 【参考方案1】:

我的 SSL 证书与 .html 文件完美配合。我的 .manifest 和 .ipa 文件有问题。

我为 SSL 所做的是创建实现以下内容的 MyHTTPConnection 类:

- (NSArray *)sslIdentityAndCertificates

   SecIdentityRef identityRef = NULL;
   SecCertificateRef certificateRef = NULL;
   SecTrustRef trustRef = NULL;
   NSString *thePath = [[NSBundle mainBundle] pathForResource:@"server" ofType:@"pfx"];
   NSData *PKCS12Data = [[NSData alloc] initWithContentsOfFile:thePath];
   CFDataRef inPKCS12Data = (__bridge CFDataRef)PKCS12Data;
   CFStringRef password = CFSTR("test123");
   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:(__bridge id)identityRef, (__bridge id)certificateRef, nil];

   return result;

然后在 App Delegate 中,我刚刚将此自定义连接类设置为 httpServer

 [httpServer setConnectionClass:[MyHTTPConnection class]];

您需要做的最后一件事是将server.pfx 证书添加到捆绑包中。我在this tutorial 之后创建了证书。我只是做了,直到你有 server.crt 文件。然后我在this website 中将其转换为pfx12。我这样做是因为 p12 证书不起作用,我有 this problem。

克里斯,你能否编辑一下你的条目,解释一下你是如何做清单的。我想做和你一模一样的事,但是我遇到了你需要打开的 URL 的问题。

【讨论】:

很抱歉,我不再为该项目工作。您所说的 .manifest 是您放在服务器上的 .plist 文件? Xcode 为你生成所有这些东西,你应该有这样的东西:pastebin.com/8kx9fW2L 我知道。我让一切都在 webServer 上运行。问题是我希望能够从设备本身安装应用程序。为此,我将 .ipa 和 manifest.plist 下载到设备中。然后我需要在本地创建一个 Web 服务器,以便 Safari 可以访问下载的文件。但是我遇到了 SSL 和 .plist 文件的麻烦。无论如何,谢谢。 我遇到了完全相同的问题,但现在我没有找到任何解决方案,对不起... @nicoyuste 你好。您找到解决问题的方法了吗?我也有同样的问题。有没有可能实现? 你好。是的,我确实找到了解决方案,这是可能的。可悲的是,我不久前做了这个项目,我已经不记得我是如何解决所有问题的了。 :(

以上是关于带有 SSL 和证书的 iPhoneHTTPServer的主要内容,如果未能解决你的问题,请参考以下文章

带有 HTTPS 的 NXLog:如何配置 SSL 和证书?

使用 ssl 证书和带有卷的密钥部署 postgresql docker

使用带有 SSL 证书的 PHP cURL 时出错

通过带有 SSL 和证书的 Phonegap 连接到 Web 服务器

带有公司签名 SSL 证书的 Python setuptools

带有自签名 ssl 证书的 prometheus 的 Https