2016-08-12 9 views
1

Я создаю приложение iOS, которое обменивается данными с веб-сервером с использованием TLS. Когда я обращаюсь к веб-серверу, он представляет сертификат на моем устройстве, и я хотел бы подтвердить, что могу доверять ему.Вручную проверить сертификат TLS (ios object-c)

У меня есть корневой сертификат, встроенный в мой проект xcode в качестве файла der. Код, который у меня до сих пор, содержит версии NSString обоих сертификатов в функции делегата NSURLConnection для проверки подлинности.

Любые идеи относительно проверки вручную?

Вот мой текущий код:

- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { 
NSLog(@"Certificate challenge"); 
if (self.stageNum==0) { 
    id <NSURLAuthenticationChallengeSender> sender=challenge.sender; 
    NSURLProtectionSpace *protectionSpace=challenge.protectionSpace; 
    SecTrustRef trust=[protectionSpace serverTrust]; 

    //Get server certificate 
    SecCertificateRef certificate=SecTrustGetCertificateAtIndex(trust, 0); 
    NSData *serverCertificateData=(__bridge NSData *)SecCertificateCopyData(certificate); 
    NSString *serverBase64Certificate=[serverCertificateData base64EncodedStringWithOptions:0]; 

    //Get our certificate 
    NSData *certData1 = [[NSData alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"SUMOSRoot" ofType:@"der"]]; 
    NSString *certBase64=[certData1 base64EncodedStringWithOptions:0]; 

    //Heres where I need to compare the certificates 
    // 
    // 

    [sender useCredential:[NSURLCredential credentialForTrust:protectionSpace.serverTrust] forAuthenticationChallenge:challenge]; 
} 
} 

ответ

1

Я думаю, что этот пост решает вашу цель. Красиво написано/объяснено.

http://www.techrepublic.com/blog/software-engineer/use-https-certificate-handling-to-protect-your-ios-app/

Люди, которые слишком ленивы, чтобы открыть ссылки, я буду добавить описание здесь с поста.

enter image description here

+1

Это будет работать, но это не так идеально, потому что сертификат в конечном итоге истекает и восстанавливается, и, следовательно, больше не будет соответствовать ожидаемому хешу. Лучше захватить открытый ключ из объекта доверия и сравнить его с ожидаемым ключом. Таким образом, он будет продолжать доверять серверу даже после того, как администратор восстановит сертификат (при условии, что администратор не изменит ключ). – dgatwood

+0

Спасибо за ссылку! Я посмотрю –

+0

Работает ли эта ссылка? – Harsh

1

Я не уверен, почему вы хотите, чтобы получить NSString представление. Как только у вас есть SecTrustRef, вы можете позвонить SecTrustCopyPublicKey, чтобы скопировать открытый ключ в SecKeyRef, а затем сравнить его с исходными ключевыми данными (необработанные байты). Если открытые ключи совпадают, вы должны принять сертификат.

Этот метод называется «сертификация пиннинга», и я уверен, что, вероятно, здесь есть несколько ответов на переполнение стека, которые могут предоставить полные образцы кода, если вы ищете этот термин.

Возможно, вы также можете сравнить сертификаты, но это, вероятно, не то, что вы хотите сделать, потому что сертификаты периодически истекают и должны обновляться. Если вы сравните ключ, он будет продолжать работать, даже если они будут восстанавливать сертификат (при условии, что они регенерируют его с помощью той же пары private/public key).

Или, если вы желаете привязать его к определенному долгосрочному сертификату частного корня, вы можете просто добавить это в список доверенных привязок и переоценить объект доверия, с оговоркой, что это сломается, когда этот частный корень истекает срок действия сертификата. С другой стороны, если вы привяжете ключ, он сломается, если вам когда-нибудь придется поменять секретный ключ по какой-то причине ... так что это компромисс.

Конечно, лучший выбор в общем случае, если это возможно, состоит в том, чтобы получить настоящий сертификат CA и не вмешиваться в какую-либо проверку цепи, но я предполагаю, что это невозможно (например, потому что сервер находится в домене .local, на физическом устройстве, которое генерирует собственный сертификат без доступа к Интернету или по какой-либо другой причине). Поэтому для таких вещей, как безопасная связь с произвольным набором аппаратных средств в локальной сети, наилучшим подходом является ключевое закрепление. Если ключ не соответствует, попросите пользователя добавить его как новое устройство или что-то еще.

+0

Спасибо за ответ. Я буду исследовать больше о закреплении сертификата. И вы правы, невозможно использовать настоящий сертификат CA для этой ситуации –