2

我对 Objective C 和 HTTPs 很陌生。请就此事给我建议。

我需要我的 iPhone 应用程序通过 HTTPs 与我的服务器通信。我创建了自签名证书,当通过浏览器访问 URL 时,它会显示一条警告消息,表明服务器不受信任。没关系。

从我的 iPhone 应用程序发送 HTTP 请求。通过 HTTPS 我正在使用 ASIHTTPRequest。但是我收到一条错误消息“发生连接失败:SSL 问题(可能的原因可能包括错误/过期/自签名证书,时钟设置为错误日期)”。

我浏览了 Stackoverflow 并学会了以下方式:

  1. 我从浏览器下载了证书并将其包含在我的 Xcode 项目中。
  2. 将证书加载到 NSData

    NSString* fullFileName = @"myCertificate.cer"; NSString* 文件名 = [[fullFileName lastPathComponent] stringByDeletingPathExtension]; NSString* extension = [fullFileName pathExtension]; NSData *PKCS12Data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:fileName ofType:extension]];

  3. 提取身份

    [self extractIdentity:&identity and Trust:&trust fromPKCS12Data:PKCS12Data密码:@"myCertificatePasswordHere"];

  4. 通过 HTTPS 发送 HTTP 请求

    ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:myHTTPsURLHere]; [请求 setClientCertificateIdentity:identity]; [请求开始同步];

  5. 正如这里的许多人建议的那样,我还修改了 ASIHTTPRequest.m 并包括

[sslProperties setObject:(NSString *)kCFBooleanTrue forKey:(NSString *)kCFStreamSSLAllowsExpiredCertificates]; [sslProperties setObject:(NSString *)kCFBooleanTrue forKey:(NSString *)kCFStreamSSLAllowsExpiredRoots];

进入 IF 语句

   if (![self validatesSecureCertificate]) {

     NSDictionary *sslProperties = [[NSDictionary alloc] initWithObjectsAndKeys:
                                           [NSNumber numberWithBool:YES], kCFStreamSSLAllowsExpiredCertificates,
                                           [NSNumber numberWithBool:YES], kCFStreamSSLAllowsAnyRoot,
                                           [NSNumber numberWithBool:NO],  kCFStreamSSLValidatesCertificateChain,
                                           kCFNull,kCFStreamSSLPeerName,
                                           @"kCFStreamSocketSecurityLevelTLSv1_0SSLv3", kCFStreamSSLLevel,
                                           nil];

    CFReadStreamSetProperty((CFReadStreamRef)[self readStream], 
                                    kCFStreamPropertySSLSettings, 
                                    (CFTypeRef)sslProperties);


            [sslProperties release];
        }else {
            NSMutableDictionary *sslProperties = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
                                           [NSNumber numberWithBool:NO], kCFStreamSSLAllowsExpiredCertificates,
                                           [NSNumber numberWithBool:NO], kCFStreamSSLAllowsAnyRoot,
                                           [NSNumber numberWithBool:YES],  kCFStreamSSLValidatesCertificateChain,
                                           @"kCFStreamSocketSecurityLevelTLSv1_0SSLv3", kCFStreamSSLLevel,
                                           nil];

            CFReadStreamSetProperty((CFReadStreamRef)[self readStream], 
                                    kCFStreamPropertySSLSettings, 
                                    (CFTypeRef)sslProperties);

            [sslProperties setObject:(NSString *)kCFBooleanTrue forKey:(NSString *)kCFStreamSSLAllowsExpiredCertificates]; // Sergey added this line
            [sslProperties setObject:(NSString *)kCFBooleanTrue forKey:(NSString *)kCFStreamSSLAllowsExpiredRoots]; // Sergey added this line 
            [sslProperties release];
        } 

但这无济于事:(。我仍然收到一条错误消息:

  Domain=ASIHTTPRequestErrorDomain Code=1 "A connection failure occurred: SSL problem (Possible causes may include a bad/expired/self-signed certificate, clock set to wrong date)"

请告诉我如何通过 HTTPs 进行 ASIHTTPRequest 以便客户端证书得到我的服务器的验证?我不想使用私有 api...

非常感谢!

4

1 回答 1

1

ASIHttpRequest 和 iOS 5 确实存在一个错误。对我有用的一个很好的修复是这个:修复了 james-chalfant 在 iOS 5 (alternate) 上的自签名客户端证书

于 2012-12-28T10:48:49.227 回答