Закрепление SSL на iOS

Чтобы повысить безопасность моего приложения и защитить пользователя от MITM-атак, я пытаюсь закрепить SSL с помощью своего самозаверяющего сертификата, следуя содержанию этот пост.

Поэтому я использую следующий код для сравнения сертификата, который я получаю с сервера, с сертификатом, включенным в приложение.

- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
    SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;
    SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, 0);
    NSData *remoteCertificateData = CFBridgingRelease(SecCertificateCopyData(certificate));
    NSLog(@"Remote Certificate Data Length: %d",[remoteCertificateData length]);
    NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"apache" ofType:@"crt"];
    NSData *localCertData = [NSData dataWithContentsOfFile:cerPath];
    NSLog(@"Local Certificate Data Length: %d",[localCertData length]);
    if ([remoteCertificateData isEqualToData:localCertData]) {
        NSURLCredential *credential = [NSURLCredential credentialForTrust:serverTrust];
        [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
    }
    else {
        [[challenge sender] cancelAuthenticationChallenge:challenge];
    }
}

Единственные вещи, которые отличаются между моим кодом и кодом в сообщении блога, на которое я ссылаюсь, — это имя и расширение (от .cer до .crt) для ресурса, представляющего мой сертификат, и два NSLogs, которые я добавил, которые пригодятся позже, чтобы показать в чем проблема.

Фактически, когда этот код выполняется, я получаю этот вывод:

2013-05-22 16:08:53.331 HTTPS Test[5379:c07] Remote Certificate Data Length: 880
2013-05-22 16:09:01.346 HTTPS Test[5379:c07] Local Certificate Data Length: 1249

Очевидно, что сравнение между локальным и удаленным сертификатами не удается, потому что длина данных отличается, и поэтому также не удается закрепить.

Почему это происходит и как я могу решить эту проблему?


person BigLex    schedule 22.05.2013    source источник
comment
Думали ли вы просто сохранить возвращенные данные сертификата в файл и использовать его? В противном случае выполните сравнение данных и посмотрите, что отличается.   -  person Marcus Adams    schedule 22.05.2013
comment
Нет, я не думал об этом! Хорошая идея, немедленно попробую!   -  person BigLex    schedule 23.05.2013
comment
Если вы используете Alamofire, проверьте этот jayprakashdubey. blogspot.in/2017/07/   -  person Jayprakash Dubey    schedule 21.07.2017


Ответы (1)


Я была такая же проблема. Проблема, вероятно, в том, что вы не преобразовали файл .crt в правильный формат. iOS и OSX ищут ваш сертификат в формате .der. Вам нужно использовать openssl для преобразования. Вот очень полезная статья на эту тему. Мой общедоступный сертификат пришел с сервера Apache (я предполагаю, что и ваш). После просмотра документации openssl я смог понять, как заставить это работать.

1) Откройте терминал и перейдите в каталог, где находится ваш .crt.

2) Выполните эту команду:

openssl x509 -in your_cert.crt -outform der -out your_output_name.der

Это создаст выходной файл с именем your_output_file.der. Вы должны импортировать это в свой проект xCode и ссылаться на него в

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

метод вашей NSURLConnectionDelegate реализации.

Надеюсь, это поможет!

person i2097i    schedule 20.02.2014