Objective-C / Какао: Как мне принять плохой сертификат сервера?
Используя NSURLRequest , я пытаюсь получить доступ к веб-сайту с просроченным сертификатом. Когда я отправляю запрос, вызывается мой метод делегата connection: didFailWithError со следующей информацией:
-1203, NSURLErrorDomain, bad server certificate
Мои поиски нашли только одно решение: метод скрытого класса в NSURLRequest:
[NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:myHost];
Однако я не хочу использовать частные API в производственном приложении по очевидным причинам.
Есть предложения, что делать? Нужно ли мне использовать API CFNetwork, и если да, то два вопроса:
- Любой пример кода, который я могу использовать для начала? Я не нашел ни одного в Интернете.
- Если я использую для этого CFNetwork, нужно ли мне полностью отказаться от NSURL?
РЕДАКТИРОВАТЬ:
В iPhone OS 3.0 появился поддерживаемый метод для этого. Подробнее здесь: Как использовать NSURLConnection для подключения к SSL для ненадежного сертификата?
Ответов (6)6
В iPhone OS 3.0 появился поддерживаемый способ сделать это, не требующий низкоуровневых API CFNetwork. Подробнее здесь:
Как использовать NSURLConnection для подключения к SSL для ненадежного сертификата?
Я столкнулся с той же проблемой - я разрабатывал клиент SOAP, а сервер разработки имеет сертификат собственного производства. Я не смог решить проблему даже с помощью этого метода, поскольку я использовал не NSURL, а (плохо документированные и, по-видимому, заброшенные) методы WS, и решил пока (внутренне) просто использовать не-SSL связь.
Сказав это, однако, возникает вопрос, если вы не хотите использовать частный API в производственном приложении, следует ли разрешать доступ к сайту с помощью хитрого сертификата?
Я процитирую Йенса Альфке :
Это не просто теоретическая проблема безопасности.
Согласно
последним отчетам, около 25% общедоступных DNS-серверов были скомпрометированы и могут направлять пользователей на фишинговые / вредоносные / рекламные сайты, даже
если они правильно вводят доменное имя. Единственное, что защищает вас
от этого, - это проверка SSL-сертификата.
Можете ли вы создать самоподписанный сертификат и добавить свой собственный центр сертификации в доверенные центры сертификации? Я не совсем уверен, как это будет работать на iPhone, но я предполагаю, что в Mac OS X вы бы добавили их в Связку ключей.
Вас также может заинтересовать этот пост Re: Как справиться с ошибкой неверного сертификата в NSURLDownload
Поддерживаемый способ сделать это требует использования 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);
Another option would be to use an alternate connection library.
I am a huge fan of AsyncSocket and it has support for self signed certs
http://code.google.com/p/cocoaasyncsocket/
Взгляните, я думаю, что он более надежен, чем стандартный NSURLRequests.