Pergunta

Usando Solicitação NSURL, estou tentando acessar um site que possui um certificado expirado.Quando eu envio a solicitação, meu conexão: didFailWithError O método delegado é invocado com as seguintes informações:

-1203, NSURLErrorDomain, bad server certificate

Minhas pesquisas encontraram apenas uma solução:um método de classe oculto em NSURLRequest:

[NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:myHost];

No entanto, não quero usar APIs privadas em um aplicativo de produção por motivos óbvios.

Alguma sugestão sobre o que fazer?Preciso usar APIs CFNetwork e, em caso afirmativo, duas perguntas:

  • Algum código de exemplo que eu possa usar para começar?Não encontrei nenhum online.
  • Se eu usar CFNetwork para isso, terei que abandonar totalmente o NSURL?

EDITAR:

O iPhone OS 3.0 introduziu um método compatível para fazer isso.Mais detalhes aqui: Como usar o NSURLConnection para conectar-se ao SSL para um certificado não confiável?

Foi útil?

Solução 3

O iPhone OS 3.0 introduziu uma maneira suportada de fazer isso que não requer APIs CFNetwork de nível inferior.Mais detalhes aqui:

Como usar o NSURLConnection para conectar-se ao SSL para um certificado não confiável?

Outras dicas

A maneira suportada de fazer isso requer o uso do CFNetwork.Você precisa anexar um kCFStreamPropertySSLSettings ao fluxo que especifica kCFStreamSSLValidatesCertificateChain == kCFBooleanFalse.Abaixo está um código rápido que faz isso, menos a verificação de resultados válidos e a limpeza.Depois de fazer isso, você pode usar CFReadStreamRead() para obter os dados.

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);

Se for para um servidor interno para fins de teste, por que não apenas importar o certificado do servidor de teste para o KeyChain e definir configurações de confiança personalizadas?

Encontrei o mesmo problema - estava desenvolvendo um cliente SOAP e o servidor de desenvolvimento possui um certificado "caseiro".Não consegui resolver o problema mesmo usando esse método, pois não estava usando NSURL, mas sim os métodos WS (mal documentados e aparentemente abandonados), e decidi por enquanto (internamente) apenas usar um não-SSL conexão.

Dito isto, no entanto, a questão que vem à mente é: se você não deseja usar uma API privada em um aplicativo de produção, deveria permitir o acesso a um site com um certificado duvidoso?

vou citar Jens Alfke:

Isso não é apenas um problema teórico de segurança.Algo
cerca de 25% dos servidores DNS públicos foram comprometidos, de acordo com
relatórios recentes e pode direcionar os usuários para sites de phishing/malware/anúncios, mesmo
se eles inserirem o nome de domínio corretamente.A única coisa que protege você
a partir disso está a verificação do certificado SSL.

Você pode criar um certificado autoassinado e adicionar sua autoridade de certificação personalizada às CAs confiáveis?Não tenho certeza de como isso funcionaria no iPhone, mas presumo que no Mac OS X você os adicionaria ao Keychain.

Você também pode estar interessado neste post Ré:Como lidar com erro de certificado incorreto em NSURLDownload

Outra opção seria usar uma biblioteca de conexão alternativa.

Sou um grande fã do AsyncSocket e ele oferece suporte para certificados autoassinados

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

Dê uma olhada, acho que é muito mais robusto que o NSURLRequests padrão.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top