目标C:SSL固定

时间:2014-12-02 18:30:37

标签: objective-c ssl nsurlconnection nsurlrequest nsurlconnectiondelegate

我已经在我的类中实现了NSURLConnectionDataDelegate,并且我实现了该方法:

- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge;

但是当我制作新的NSURLConnection时,这个方法并没有被调用。为什么?问题出在哪儿?连接是SSL连接。

我查看了一个通过互联网下载的示例项目(我不记得在哪里),这个项目工作得很好,但是如果我在项目中做了一些步骤,那就不行了。我需要任何外部库或在项目中设置一些东西?你可以建议我一个for-dummies指南吗?

编辑1: 在我使用的示例中:

NSURL *httpsURL = [NSURL URLWithString:@"https://secure.skabber.com/json/"];
NSURLRequest *request2 = [NSURLRequest requestWithURL:httpsURL cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:15.0f];
NSURLConnection *connection = [NSURLConnection connectionWithRequest:request2 delegate:self];
[connection start];

但我想使用任何类型的NSURLConnection。

编辑2:

这是我的完整代码:

@interface ConnectionDelegate : NSObject<NSURLConnectionDataDelegate>
@property (strong, nonatomic) NSURLConnection *connection;
@property (strong, nonatomic) NSMutableData *responseData;
- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge;
-(void)testHTTPRequest;
@end

@implementation ConnectionDelegate
-(void)testHTTPRequest
{
    NSURL *httpsURL = [NSURL URLWithString:@"https://secure.skabber.com/json/"];
    NSURLRequest *request = [NSURLRequest requestWithURL:httpsURL cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:15.0f];
    self.connection = [NSURLConnection connectionWithRequest:request delegate:self];
    [self.connection start];

    if ([self isSSLPinning]) {
        [self printMessage:@"Making pinned request"];
    }
    else {
        [self printMessage:@"Making non-pinned request"];
    }
}

- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
    SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;
    SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, 0);
    NSData *remoteCertificateData = CFBridgingRelease(SecCertificateCopyData(certificate));
    NSData *skabberCertData = [self skabberCert];

    if ([remoteCertificateData isEqualToData:skabberCertData] || [self isSSLPinning] == NO) {

        if ([self isSSLPinning] || [remoteCertificateData isEqualToData:skabberCertData]) {
            [self printMessage:@"The server's certificate is the valid secure.skabber.com certificate. Allowing the request."];
        }
        else {
            [self printMessage:@"The server's certificate does not match secure.skabber.com. Continuing anyway."];
        }

        NSURLCredential *credential = [NSURLCredential credentialForTrust:serverTrust];
        [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
    }
    else {
        [self printMessage:@"The server's certificate does not match secure.skabber.com. Canceling the request."];
        [[challenge sender] cancelAuthenticationChallenge:challenge];
    }
}


- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    if (self.responseData == nil) {
        self.responseData = [NSMutableData dataWithData:data];
    }
    else {
        [self.responseData appendData:data];
    }
}


- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    NSString *response = [[NSString alloc] initWithData:self.responseData encoding:NSUTF8StringEncoding];
    [self printMessage:response];
    self.responseData = nil;
}


- (NSData *)skabberCert
{
    NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"secure.skabber.com" ofType:@"cer"];
    return [NSData dataWithContentsOfFile:cerPath];
}

- (void)printMessage:(NSString *)message
{
    Log(@"%@",message);
}


- (BOOL)isSSLPinning
{
    NSString *envValue = [[[NSProcessInfo processInfo] environment] objectForKey:@"SSL_PINNING"];
    return [envValue boolValue];
}

@end

如果我在连接上设置断点:willSendRequestForAuthenticationChallenge:程序不会输入。

0 个答案:

没有答案