【发布时间】:2012-04-10 02:56:01
【问题描述】:
我正在尝试在 iOS 应用中构建 HTTPS 服务器,以充当我的网络应用和外部服务器之间的代理。
感谢 CFSocketRef 或使用 GCDAsyncSocket 库,我已经设法通过侦听套接字来创建 HTTP 服务器。 我还成功地使用 GCDAsyncSocket 库制作了一个运行 HTTPS 服务器的 Mac 应用程序,这要归功于我的方法“secureSocket:”,它可以保护连接:
- (void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket
{
// (...)
// secure the connection
[self secureSocket:newSocket];
// (...)
}
- (void)secureSocket:(GCDAsyncSocket *)sock
{
// The root self-signed certificate I have created
NSString *certificatePath = [[NSBundle mainBundle] pathForResource:@"certificate" ofType:@"cer"];
NSData *certData = [[NSData alloc] initWithContentsOfFile:certificatePath];
CFDataRef certDataRef = (CFDataRef)certData;
SecCertificateRef cert = SecCertificateCreateWithData(NULL, certDataRef);
[certData release];
// the "identity" certificate
SecIdentityRef identityRef;
SecIdentityCreateWithCertificate(NULL, cert, &identityRef);
// the certificates array, containing the identity then the root certificate
NSArray *certs = [[NSArray alloc] initWithObjects:(id)identityRef, (id)cert, nil];
// the SSL configuration
NSMutableDictionary *settings = [NSMutableDictionary dictionaryWithCapacity:3];
[settings setObject:[NSNull null] forKey:(NSString *)kCFStreamSSLPeerName];
[settings setObject:[NSNumber numberWithBool:YES] forKey:(NSString *)kCFStreamSSLAllowsAnyRoot];
[settings setObject:[NSNumber numberWithBool:YES] forKey:(NSString *)kCFStreamSSLAllowsExpiredRoots];
[settings setObject:[NSNumber numberWithBool:YES] forKey:(NSString *)kCFStreamSSLAllowsExpiredCertificates];
[settings setObject:[NSNumber numberWithBool:NO] forKey:(NSString *)kCFStreamSSLValidatesCertificateChain];
[settings setObject:(NSString *)kCFStreamSocketSecurityLevelNegotiatedSSL forKey:(NSString*)kCFStreamSSLLevel];
[settings setObject:certs forKey:(NSString *)kCFStreamSSLCertificates];
[settings setObject:[NSNumber numberWithBool:YES] forKey:(NSString *)kCFStreamSSLIsServer];
[sock startTLS:settings];
[certs release];
}
我使用的证书是我使用 Keychain Access 创建的自签名服务器 SSL 证书。 所以我知道我必须给系统一个配置集,其中包含一个包含身份和证书的数组。它在我的 Mac 应用上运行良好。
问题是在我的 iOS 应用程序的 HTTP 服务器上启用 SSL。 创建身份的方法“SecIdentityCreateWithCertificate()”在 iOS 上不存在,我不知道如何以另一种方式创建身份。
如何在 iOS 上创建 SecIdentityRef(启用 SSL 服务器端)?我是否错过了,例如将公钥/私钥存储在我的应用中,或者其他什么?非常感谢。
【问题讨论】:
-
在 CocoaAsyncSocket v7.4 中进行了更改,一些旧的选项键现在不可用并且会抛出异常。使用 GCDAsyncSocketManuallyEvaluateTrust 并在 -socket:didReceiveTrust: 委托中进行评估。在gist.github.com/hlung/6432966 中查看我的示例
标签: ios networking ssl https