简体   繁体   English

用于在iOS上运行HTTPS服务器的SSL身份证书

[英]SSL Identity Certificate to run an HTTPS Server on iOS

I'm trying to build an HTTPS server in an iOS app , in order to act as a proxy between my web-app and my external server. 我正在尝试在iOS应用程序中构建HTTPS服务器 ,以便充当我的Web应用程序和外部服务器之间的代理。

I have managed to make an HTTP server by listening to a socket, either thanks to CFSocketRef or using the GCDAsyncSocket library. 我已经设法通过监听套接字来创建HTTP服务器,这要归功于CFSocketRef或使用GCDAsyncSocket库。 I have also succeed to make a Mac app running an HTTPS server, using the GCDAsyncSocket library and thanks to my method "secureSocket:" below which secures the connection: 我还成功地使用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];
}

The certificate I'm using is a self-signed server SSL certificate I have created with Keychain Access. 我正在使用的证书是我使用Keychain Access创建的自签名服务器SSL证书。 So I understand that I have to give the system a configuration set with an array containing an identity and a certificate. 所以我理解我必须给系统一个配置集,其中包含一个包含身份和证书的数组。 And it works fine on my Mac app. 它在我的Mac应用程序上工作正常。

The problem is to enable the SSL on the HTTP server of my iOS app. 问题是在我的iOS应用程序的HTTP服务器上启用SSL。 The method "SecIdentityCreateWithCertificate()" which creates the identity doesn't exist on iOS and I don't know how to create an identity another way. 创建标识的方法“SecIdentityCreateWithCertificate()”在iOS上不存在,我不知道如何以另一种方式创建标识。

How to create an SecIdentityRef on iOS (to enable SSL server side)? 如何在iOS上创建SecIdentityRef(启用SSL服务器端)? Did I miss something like to store the public/private key in my app, or something else? 我是否想念将公钥/私钥存储在我的应用程序或其他内容? Thank you so much. 非常感谢。

I will post a separate answer, as comments are not suitable for code sharing. 我将发布一个单独的答案,因为评论不适合代码共享。
Here is what I use to import my PKCS12: 这是我用来导入我的PKCS12:

CFArrayRef keyref = NULL;
OSStatus sanityChesk = SecPKCS12Import((__bridge CFDataRef)p12Data, 
                                       (__bridge CFDictionaryRef)[NSDictionary 
                                                                  dictionaryWithObject:password 
                                                                  forKey:(__bridge id)kSecImportExportPassphrase], 
                                       &keyref);

if (sanityChesk != noErr) {
    NSLog(@"Error while importing pkcs12 [%d]", sanityChesk);
    return nil;
}

NSArray *keystore = (__bridge_transfer NSArray *)keyref;

The complete p12 content will be in the keystore array. 完整的p12内容将位于密钥库阵列中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM