Utilice HttpDNS para conexiones IP directas en iOS para evitar el secuestro de DNS
El primer paso para enviar una solicitud HTTPS es realizar un protocolo de enlace SSL/TLS. El proceso general es el siguiente:
En el proceso anterior, el tercer paso está relacionado con HTTPDNS. El cliente necesita verificar que el servidor emitió el Certificado, el proceso de verificación incluye principalmente los dos puntos siguientes:
Si se verifican los dos puntos anteriores, demuestra que el servidor actual es confiable. Cuando el cliente usa HTTPDNS para resolver el nombre de dominio, el host en la URL de solicitud será reemplazado por la IP resuelta por HTTPDNS. Por lo tanto, en el segundo paso de la verificación del certificado, el nombre de dominio no coincidirá, lo que resultará en un SSL/fallido. Apretón de manos TLS.
Para el problema de discrepancia de nombres de dominio, se puede adoptar la siguiente solución: conecte el segundo paso del proceso de verificación del certificado, reemplace directamente la IP con el nombre de dominio original y luego realice la verificación del certificado.
Método proxy para que el cliente reciba solicitudes de desafío del servidor - URLSession:task:didReceiveChallenge:completionHandler: desde el host en el primer encabezado (tenga en cuenta el primer punto: la configuración del campo HOST en el encabezado de solicitud HTTP ), si la hostia no se obtiene de la cabeza. Si el host no se obtiene de la información del encabezado, vaya a la URL para obtener el host (baje a resolución LocalDNS sin reemplazo), luego obtenga el host con su propio método --evaluateServerTrust: forDomain: cree una política de verificación de certificado de política SSL, y luego verificar el certificado.
SNI (Server Name Indication) es una extensión SSL/TLS que resuelve el problema de utilizar múltiples nombres de dominio y certificados con un solo servidor. Así es como funciona:
Antes de conectarse al servidor para establecer un enlace SSL, envía el nombre de dominio (nombre de host) del sitio web que desea visitar y el servidor devuelve un certificado apropiado basado en ese dominio. nombre.
Actualmente, la mayoría de los sistemas operativos y navegadores ofrecen un buen soporte para las extensiones SNI, y OpenSSL 0.9.8 también tiene esta funcionalidad incorporada.
En el proceso anterior, cuando el cliente usa HTTPDNS para resolver el nombre de dominio, el host en la URL de solicitud será reemplazado por la IP resuelta por HttpDNS, lo que dará como resultado que el servidor reciba la dirección IP del cliente. durante el protocolo de enlace SSL/TLS. La llegada de clientHello viene con un SNI para la IP resuelta del host, por lo que no se puede encontrar un certificado coincidente y se devuelve el certificado predeterminado o no se devuelve nada, lo que provoca que el protocolo de enlace SSL/TLS no tenga éxito.
Por ejemplo, cuando necesita acceder a recursos CDN a través de HTTPS, los sitios CDN tienden a servir a muchos dominios, por lo que debe especificar un certificado de dominio específico para comunicarse a través de SNI.
En el escenario de aplicación SNI (certificado HTTPS múltiple de IP única), la biblioteca de red de capa superior de iOS NSURLConnection/NSURLSession no proporciona una interfaz para configurar el campo SNI, por lo que debe usar un nivel de socket La biblioteca de red subyacente, como CFNetwork, implementa un esquema de adaptación de solicitud de red directa IP. Apple proporciona orientación en "Temas de programación de redes" sobre cómo especificar nombres de host TLS de la siguiente manera:
La forma en que usamos CFNetwork en solicitudes de red HTTP se detalla en [2].
Apple - Comunicación con servidores HTTP
Apple - Evaluación de confianza del servidor HTTPS - Error en el nombre del servidor
Apple - Confianza del servidor HTTPS.
Evaluación: confiar en un certificado específico
[1]: descripción del escenario de conexión directa IP del escenario HTTPS
[2]: solicitud HTTP mediante CFNetwork