Используя NSURLRequest, я пытаюсь получить доступ к веб-сайту с просроченным сертификатом. Когда я отправляю запрос, вызывается мой метод делегата соединение: didFailWithError со следующей информацией:
-1203, NSURLErrorDomain, bad server certificate
Мои поиски нашли только одно решение: метод скрытого класса в NSURLRequest:
[NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:myHost];
Однако я не хочу использовать частные API в производственном приложении по очевидным причинам.
Есть предложения, что делать? Нужно ли мне использовать API CFNetwork, и если да, то два вопроса:
Обновлено:
iPhone OS 3.0 представила поддерживаемый метод для этого. Подробнее здесь: Как использовать NSURLConnection для подключения к SSL для ненадежного сертификата?





Я столкнулся с той же проблемой - я разрабатывал клиент SOAP, а сервер разработки имеет сертификат собственного производства. Я не смог решить проблему даже с помощью этого метода, поскольку я использовал не NSURL, а (плохо документированные и, по-видимому, заброшенные) методы WS, и решил пока (внутренне) просто использовать не-SSL связь.
Сказав это, однако, возникает вопрос, если вы не хотите использовать частный API в производственном приложении, следует ли разрешать доступ к сайту с помощью хитрого сертификата?
Процитирую Йенс Альфке:
That's not just a theoretical security problem. Something
like 25% of public DNS servers have been compromised, according to
recent reports, and can direct users to phishing/malware/ad sites even
if they enter the domain name properly. The only thing protecting you
from that is SSL certificate checking.
Можете ли вы создать самоподписанный сертификат и добавить свой собственный центр сертификации в доверенные центры сертификации? Я не совсем уверен, как это будет работать на iPhone, но я предполагаю, что в Mac OS X вы бы добавили их в Связку ключей.
Вас также может заинтересовать этот пост Re: Как справиться с ошибкой неверного сертификата в NSURLDownload
Если это внутренний сервер для целей тестирования, почему бы просто не импортировать сертификат тестового сервера в KeyChain и не установить пользовательские настройки доверия?
Поддерживаемый способ сделать это требует использования 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);
Другой вариант - использовать альтернативную библиотеку подключений.
Я большой поклонник AsyncSocket, и он поддерживает самоподписанные сертификаты.
http://code.google.com/p/cocoaasyncsocket/
Взгляните, я думаю, что он более надежен, чем стандартный NSURLRequests.
В iPhone OS 3.0 появился поддерживаемый способ сделать это, не требующий низкоуровневых API CFNetwork. Подробнее здесь:
Как использовать NSURLConnection для подключения к SSL для ненадежного сертификата?
Данный сайт находится в нашей тестовой среде, доступной только для внутреннего пользования. Я полагаю, что сетевые администраторы слишком дешевы или слишком ленивы, чтобы поддерживать для этого действующие сертификаты. Конечно, наша производственная среда имеет действующий сертификат. Поскольку эта функция уклонения от сертификатов не будет включена или не понадобится в производственной среде, я мог бы использовать частный API только для тестирования. Я по-прежнему предпочел бы сделать это «правильным» способом, поскольку я бы вернулся к исходной точке, если бы частный API когда-либо был выдернут.