简体   繁体   English

如何在ASIHTTPRequest中包含客户端证书?

[英]How to include Client Certificate with ASIHTTPRequest?

I am very new to Objective C and HTTPs. 我对Objective C和HTTP非常陌生。 Please advise me on this matter. 请给我这件事的建议。

I need my iPhone application to communicate with my server over HTTPs. 我需要我的iPhone应用程序通过HTTP与服务器通信。 I created self-signed certificate and when accessing URLs via browsers it works though displays a warning message that the server is untrusted. 我创建了自签名证书,并且通过浏览器访问URL时,尽管显示警告消息,表明服务器不受信任,但它仍然有效。 That's ok. 没关系。

To send HTTP requests from my iPhone App. 从我的iPhone App发送HTTP请求。 over HTTPS I am using ASIHTTPRequest. 通过HTTPS我正在使用ASIHTTPRequest。 But I am getting an error message "A connection failure occurred: SSL problem (Possible causes may include a bad/expired/self-signed certificate, clock set to wrong date)". 但是我收到一条错误消息“发生连接失败:SSL问题(可能的原因可能包括错误的/过期的/自签名的证书,时钟设置为错误的日期)”。

I browsed around Stackoverflow and learned to do it the following way: 我浏览了Stackoverflow,并学习了以下方法:

  1. I downloaded Certificate from the browser and included it to my Xcode project. 我从浏览器下载了证书,并将其包含在我的Xcode项目中。
  2. Load certificate to NSData 将证书加载到NSData

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

  3. Exctract identity 提取身份

    [self extractIdentity:&identity andTrust:&trust fromPKCS12Data:PKCS12Data password:@"myCertificatePasswordHere"]; [从PKCS12数据:PKCS12数据密码:@“ myCertificatePasswordHere”中自我提取身份:&identity andTrust:&trust;];

  4. Send HTTP Request over HTTPS 通过HTTPS发送HTTP请求

    ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:myHTTPsURLHere]; ASIHTTPRequest * request = [ASIHTTPRequest requestWithURL:myHTTPsURLHere]; [request setClientCertificateIdentity:identity]; [请求setClientCertificateIdentity:identity]; [request startSynchronous]; [request startSynchronous];

  5. As many people here suggested I also modified ASIHTTPRequest.m and included 正如许多人建议的那样,我还修改了ASIHTTPRequest.m并包含了

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

into an IF statement 成为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];
        } 

But it does not help :(. I am still getting an error message: 但这无济于事:(。我仍然收到错误消息:

  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)"

Please advise me how to make ASIHTTPRequest over HTTPs so that Client Certificate gets verified by my server? 请告诉我如何通过HTTP进行ASIHTTPRequest,以便客户端证书由我的服务器验证? I do not want to use private api... 我不想使用私人API ...

Thank you very much! 非常感谢你!

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

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

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