在iOS 5.0/5.0.1上,使用SSL的ASIHTTPRequest失败

b_b*_*uce 4 ssl https asihttprequest ios

我正在使用ASIHTTPRequest v1.8.1来发出HTTPS请求.问题是它在iOS 5.0和5.0.1上不起作用,而在5.1和5.1.1上它可以正常工作.代码很简单:

__block ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:RemoteNotiURL]];
[request setPostValue:@"i" forKey:@"plat"];
[request setPostValue:token forKey:@"token"];
[request setValidatesSecureCertificate:NO];

[request setCompletionBlock:^{
    NSLog(@"done");
}];

[request setFailedBlock:^{
    NSLog(@"error = %@", [request error]);

}];

[request startAsynchronous];
Run Code Online (Sandbox Code Playgroud)

RemoteNotiURL是一个像https://xxx.example.com这样的URL

错误是:

error = Error 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)" UserInfo=0x18460b0 {NSUnderlyingError=0x1853ab0 "The operation couldn’t be completed. (OSStatus error -9800.)", NSLocalizedDescription=A connection failure occurred: SSL problem (Possible causes may include a bad/expired/self-signed certificate, clock set to wrong date)}
Run Code Online (Sandbox Code Playgroud)

我该怎么办?

Ign*_*eso 13

正如@JosephH所说,该解决方案涉及修改ASIHTTPRequest.m以更改sslProperties字典的kCFStreamSSLLevel属性.在此文件中查找注释// Tell CFNetwork not to validate SSL certificates

在这个评论下有一个if子句

if (![self validatesSecureCertificate]) {
        // see: http://iphonedevelopment.blogspot.com/2010/05/nsstream-tcp-and-ssl.html

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

        CFReadStreamSetProperty((CFReadStreamRef)[self readStream], 
                                kCFStreamPropertySSLSettings, 
                                (CFTypeRef)sslProperties);
        [sslProperties release];
    }
Run Code Online (Sandbox Code Playgroud)

像这样修改if子句

if (![self validatesSecureCertificate]) {
        // see: http://iphonedevelopment.blogspot.com/2010/05/nsstream-tcp-and-ssl.html

        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 {
        NSDictionary *sslProperties = [[NSDictionary 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 release];
    }
Run Code Online (Sandbox Code Playgroud)

这应该使请求再次起作用.验证SSL证书的请求和不验证SSL证书的请求.

在IOS 5.0.1和5.1.1上测试.

希望这可以帮助.