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 для ненадежного сертификата?

18.08.2008 21:40:01
6 ОТВЕТОВ

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

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

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

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

1
19.08.2008 10:41:42
Данный сайт находится в нашей тестовой среде и доступен только для внутреннего использования. Я предполагаю, что сетевые администраторы слишком дешевы или ленивы, чтобы поддерживать действующие сертификаты для этого. Конечно, наша производственная среда имеет действующий сертификат. Так как эта функция уклонения от сертификатов не будет включена или не нужна в производстве, я мог бы использовать частный API только для тестирования. Я все еще предпочел бы сделать это «правильным» способом, так как я бы вернулся на круги своя, если бы частный API был когда-либо выдернут.
Mike McMaster 19.08.2008 16:17:34

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

Вы также можете быть заинтересованы в этом сообщении Re: Как справиться с ошибкой сертификата в NSURLDownload

1
21.08.2008 16:42:46

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

3
18.10.2008 20:22:44

Поддерживаемый способ сделать это требует использования 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);
8
29.10.2008 06:06:16

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

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

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

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

0
21.11.2008 19:06:41
РЕШЕНИЕ

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

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

2
23.05.2017 12:34:58