Objective-C/Какао:Как мне принять неверный сертификат сервера?

StackOverflow https://stackoverflow.com/questions/15266

  •  08-06-2019
  •  | 
  •  

Вопрос

Используя Запрос NSURL, Я пытаюсь получить доступ к веб-сайту, у которого истек срок действия сертификата.Когда я отправляю запрос, мой соединение:didFailWithError метод делегирования вызывается со следующей информацией:

-1203, NSURLErrorDomain, bad server certificate

Мои поиски привели только к одному решению:скрытый метод класса в NSURLRequest:

[NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:myHost];

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

Есть какие-нибудь предложения о том, что делать?Нужно ли мне использовать CFNetwork API, и если да, то два вопроса:

  • Есть какой-нибудь пример кода, который я могу использовать для начала?Я не нашел ни одного в Интернете.
  • Если я использую CFNetwork для этого, должен ли я полностью отказаться от NSURL?

Редактировать:

iPhone OS 3.0 представила поддерживаемый метод для этого.Более подробная информация здесь: Как использовать NSURLConnection для подключения по протоколу SSL для получения ненадежного сертификата?

Это было полезно?

Решение 3

iPhone OS 3.0 представила поддерживаемый способ сделать это, который не требует низкоуровневых API CFNetwork.Более подробная информация здесь:

Как использовать NSURLConnection для подключения по протоколу SSL для получения ненадежного сертификата?

Другие советы

Поддерживаемый способ сделать это требует использования CFNetwork.Вам нужно всего лишь присоединить kCFStreamPropertySSLSettings к потоку, который указывает kCFStreamSSLValidatesCertificateChain == kCFBooleanFalse.Ниже приведен краткий код, который делает это, за вычетом проверки правильности результатов и дополнительной очистки.Как только вы сделаете это, вы можете использовать CFReadStreamRead() для получения данных.

CFURLRef myURL = CFURLCreateWithString(kCFAllocatorDefault, CFSTR("http://www.apple.com"), NULL);
CFHTTPMessageRef myRequest = CFHTTPMessageCreateRequest(kCFAllocatorDefault, CFSTR("GET"), myURL, kCFHTTPVersion1_1);
CFReadStreamRef myStream = CFReadStreamCreateForHTTPRequest(kCFAllocatorDefault, myRequest);
CFMutableDictionaryRef myDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFDictionarySetValue(myDict, kCFStreamSSLValidatesCertificateChain, kCFBooleanFalse);
CFReadStreamSetProperty(myStream, kCFStreamPropertySSLSettings, myDict);    
CFReadStreamOpen(myStream);

Если это для внутреннего сервера в целях тестирования, почему бы просто не импортировать сертификат тестового сервера в связку ключей и не установить пользовательские параметры доверия?

Я столкнулся с той же проблемой - я разрабатывал SOAP-клиент, а сервер разработки имеет "доморощенный" сертификат.Я не смог решить проблему даже с помощью этого метода, поскольку я использовал не NSURL, а (плохо документированные и, по-видимому, заброшенные) методы WS, и решил на данный момент (внутренне) просто использовать соединение, отличное от SSL.

Сказав это, однако, возникает вопрос, который приходит на ум: если вы не хотите использовать частный API в производственном приложении, должны ли вы разрешать доступ к сайту с сомнительным сертификатом?

Я процитирую Йенс Альфке:

Это не просто теоретическая проблема безопасности.Что - то
как и 25% общедоступных DNS-серверов, были скомпрометированы, согласно
последних отчетов и может направлять пользователей на фишинговые / вредоносные программы / рекламные сайты даже
если они правильно введут доменное имя.Единственное, что защищает тебя.
исходя из этого, выполняется проверка SSL-сертификата.

Можете ли вы создать самозаверяющий сертификат и добавить свой пользовательский центр сертификации в доверенные центры сертификации?Я не совсем уверен, как это будет работать на iPhone, но я бы предположил, что в Mac OS X вы добавите их в связку ключей.

Вас также может заинтересовать этот пост Ре:Как обработать ошибку плохого сертификата в NSURLDownload

Другим вариантом было бы использовать альтернативную библиотеку подключений.

Я большой поклонник AsyncSocket, и в нем есть поддержка самоподписанных сертификатов

http://code.google.com/p/cocoaasyncsocket/

Взгляните, я думаю, что это намного надежнее, чем стандартные NSURLRequests.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top