Используя 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 для ненадежного сертификата?
Я столкнулся с той же проблемой - я разрабатывал клиент SOAP, и у сервера dev есть «доморощенный» сертификат. Я не смог решить проблему, даже используя этот метод, так как я не использовал NSURL, но (плохо документированные и явно заброшенные) методы WS, и решил пока (внутренне) просто использовать не-SSL подключение.
При этом, однако, возникает вопрос: если вы не хотите использовать частный API в производственном приложении, следует ли разрешить доступ к сайту с хитрым сертификатом?
Я процитирую Йенса Альфке :
Это не просто теоретическая проблема безопасности. Что - то
вроде 25% публичных серверов DNS были скомпрометированы, по
последним данным, и может направлять пользователей на фишинговые / вредоносных программ / рекламные сайты даже
если они входят доменное имя правильно. Единственное, что защищает вас
от этого - проверка SSL-сертификата.
Можете ли вы создать самозаверяющий сертификат и добавить свой собственный центр сертификации в доверенные центры сертификации? Я не совсем уверен, как это будет работать на 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 для ненадежного сертификата?