En servidores Internet Information Services (IIS) bajo Windows Server, la autenticación por certificado de cliente puede presentar un comportamiento anómalo: al configurar el sitio en modo Aceptar (Accept / SslNegotiateCert), el navegador no despliega el selector de certificados y la conexión finaliza abruptamente con un error ERR_CONNECTION_RESET o connection reset. Sin embargo, si la opción se cambia a Requerir (Require / SslRequireCert), la solicitud del certificado funciona correctamente [1][2].
Este problema no se origina en la configuración propia de IIS en web.config, sino en la capa del controlador de kernel de Windows HTTP.sys, donde la propiedad clientcertnegotiation del binding SSL permanece deshabilitada por defecto [2][3].
1. Diferencia técnica entre "Aceptar" y "Requerir" en IIS
IIS gestiona la negociación de certificados de cliente mediante el elemento de configuración system.webServer/security/access y sus banderas sslFlags [1]:
| Modo en IIS Manager | Bandera sslFlags | Comportamiento TLS |
|---|---|---|
| Ninguno (Ignore) | Ssl | No solicita certificado de cliente durante el handshake TLS |
| Aceptar (Accept) | Ssl, SslNegotiateCert | Solicita certificado de cliente de forma opcional; si el cliente no lo envía, la conexión continúa |
| Requerir (Require) | Ssl, SslRequireCert | Exige certificado de cliente; si el cliente no lo presenta o no es válido, rechaza la conexión con error 403.7 |
El modo Aceptar está diseñado para portales donde la autenticación por certificado es optativa (por ejemplo, acceso mediante usuario/contraseña o firma digital alternativa). Si el cliente posee un certificado válido en su almacén local, el navegador debe mostrar el desplegable de selección [1].
2. El síntoma: Connection Reset en el handshake TLS
Cuando el sitio está en modo Aceptar y un cliente intenta conectar por HTTPS, ocurre la siguiente secuencia anómala:
- El cliente inicia la negociación TLS mediante el mensaje
ClientHello. - IIS recibe la solicitud a través del controlador
HTTP.sys. - IIS intenta diferir o renegociar la solicitud del certificado de cliente durante la sesión TLS.
- HTTP.sys rechaza la renegociación o el intercambio del mensaje
CertificateRequestporque el binding SSL a nivel de kernel no tiene habilitada la negociación implícita. - La conexión TCP se interrumpe de forma abrupta antes de completar la capa de aplicación, devolviendo
ERR_CONNECTION_RESET.
Al cambiar IIS a modo Requerir, HTTP.sys solicita el certificado directamente desde la fase inicial del handshake TLS, enmascarando el fallo del binding [2].
3. Diagnóstico paso a paso
Paso 1: Verificar la configuración efectiva en IIS
Primero se debe confirmar que la sección de seguridad de IIS refleja el ajuste SslNegotiateCert:
%windir%\system32\inetsrv\appcmd.exe list config "NombreDelSitio" /section:system.webServer/security/access
La salida esperada debe incluir la bandera de negociación:
<system.webServer>
<security>
<access sslFlags="Ssl, SslNegotiateCert" />
</security>
</system.webServer>
Si sslFlags muestra únicamente Ssl, el cambio no se ha aplicado correctamente en el nivel correspondiente (sitio, aplicación o directorio).
Paso 2: Inspeccionar los enlaces SSL en HTTP.sys
HTTP.sys gestiona los bindings HTTPS independientemente del esquema de configuración de IIS. Para revisar el estado de la negociación a nivel de kernel, ejecuta en una consola de comandos con privilegios elevados [3]:
netsh http show sslcert
Para filtrar un sitio o nombre de host específico:
netsh http show sslcert hostnameport=secure.example.com:443
Analiza la propiedad Negociar certificado de cliente (Negotiate Client Certificate):
Enlaces de certificado SSL:
---------------------------
Nombre de host:puerto : secure.example.com:443
Hash del certificado : 876543210fedcba09876543210fedcba09876543
Id. de la aplicación : {00000000-0000-0000-0000-000000000000}
Nombre del almacén de certificados : MY
Comprobar revocación de certificado de cliente : Enabled
Negociar certificado de cliente : Disabled
Deshabilitar HTTP2: Not Set
Deshabilitar TLS1.3: Not Set
El parámetro Negociar certificado de cliente : Disabled es la causa directa del reinicio de conexión cuando IIS está configurado en Aceptar [2][3].
4. Solución: Activar la negociación de certificados en HTTP.sys
Para resolver la incompatibilidad, es necesario actualizar el enlace SSL en HTTP.sys habilitando la propiedad clientcertnegotiation [3].
Advertencia: El comando
netsh http update sslcertrequiere especificar obligatoriamente el hash del certificado (certhash), la ID de aplicación (appid) y el almacén (certstorename). Si se omite alguno de estos parámetros, el comando devolveráError 87: El parámetro no es correcto.
Comando de actualización
Recopila los datos devueltos por netsh http show sslcert para el binding afectado y ejecuta la actualización:
netsh http update sslcert hostnameport=secure.example.com:443 certhash=876543210fedcba09876543210fedcba09876543 appid={00000000-0000-0000-0000-000000000000} certstorename=MY clientcertnegotiation=enable
En caso de utilizar enlaces basados en IP y puerto (sin SNI), sustituye hostnameport por ipport:
netsh http update sslcert ipport=192.0.2.10:443 certhash=876543210fedcba09876543210fedcba09876543 appid={00000000-0000-0000-0000-000000000000} certstorename=MY clientcertnegotiation=enable
5. Verificación y pruebas finales
Vuelve a consultar el estado del enlace SSL para verificar la modificación [3]:
netsh http show sslcert hostnameport=secure.example.com:443
Confirma que el parámetro ha cambiado a habilitado:
Negociar certificado de cliente : Enabled
Proceso de validación:
- Reinicia el navegador web o borra la caché del estado SSL para forzar la apertura de una nueva sesión TLS (las conexiones compuestas previas no renegociarán el certificado).
- Asegúrate de que el certificado de cliente con su clave privada está instalado correctamente en el almacén personal del usuario o navegador.
- Accede a la URL del sitio mediante HTTPS.
- El navegador desplegará de inmediato el diálogo emergente para seleccionar el certificado digital disponible, permitiendo el acceso sin interrumpir la conexión TCP.
6. Consideraciones adicionales en Windows Server 2022 y TLS 1.3
En instalaciones recientes sobre Windows Server 2022, la introducción del protocolo TLS 1.3 modifica la dinámica del handshake. TLS 1.3 prohíbe la renegociación del certificado una vez establecida la conexión cifrada (renegociación posterior al handshake) [2].
Si el sitio requiere autenticación opcional con TLS 1.3 activo:
- Habilitar
clientcertnegotiation=enableen HTTP.sys obliga a solicitar el certificado durante el handshake inicial. - Si por motivos de diseño del sitio se necesita solicitar el certificado únicamente en ciertas subrutas (por ejemplo
/login), se debe desactivar TLS 1.3 en ese binding específico o deshabilitar la renegociación diferida, ya que de lo contrario HTTP.sys cerrará la conexión [2].
netsh http update sslcert hostnameport=secure.example.com:443 certhash=876543210fedcba09876543210fedcba09876543 appid={00000000-0000-0000-0000-000000000000} certstorename=MY clientcertnegotiation=enable disabletls13=enable
Conclusiones / En resumen
- El modo Aceptar en IIS no basta por sí solo: aunque
web.configcontengaSslNegotiateCert, la pila de redHTTP.sysdebe permitir la negociación a nivel de kernel. - El error
ERR_CONNECTION_RESETes sintomático: indica un fallo de renegociación TLS cuando el cliente conecta por HTTPS y HTTP.sys tieneclientcertnegotiationdesactivado. netsh http update sslcertes el comando clave: requiere proporcionarcerthash,appidycertstorenamepara evitar elError 87.- TLS 1.3 impone restricciones adicionales: la renegociación tardía de certificados de cliente no está soportada en TLS 1.3, requiriendo negociación inicial obligatoria en HTTP.sys.
📚 Fuentes consultadas
- IIS Client Certificate Settings (access Element) - Microsoft Learn
- Windows Server 2022 IIS Web site TLS 1.3 does not work with client certificate - Microsoft Tech Community
- netsh http commands - Microsoft Learn
- How to Set Up SSL on IIS - Microsoft Learn