SSL Pinning es una técnica de seguridad mediante la cual la aplicación verifica el certificado del servidor contra una huella digital o certificado conocido de antemano, en lugar de confiar en la cadena de confianza de la CA. A diferencia de la verificación estándar, el pinning evita la interceptación del tráfico a través de centros de certificación raíz fraudulentos. Según la OWASP Mobile Security Testing Guide (2025), esta técnica se encuentra entre los 3 controles recomendados para protegerse contra ataques MITM. Sin pinning, un atacante con un certificado raíz fraudulento puede descifrar todo el tráfico HTTPS de la aplicación.
Conclusiones clave
SSL Pinning es un mecanismo de seguridad mediante el cual una aplicación móvil o web recuerda un certificado de servidor de confianza o clave pública y rechaza cualquier conexión cuyo certificado no coincida con el almacenado. En el esquema HTTPS estándar, el cliente verifica el certificado a través de una cadena de confianza hasta la CA raíz — cualquier CA puede firmar un certificado para cualquier dominio. SSL Pinning elimina esta debilidad: en lugar de confiar en cientos de CA, la aplicación confía solo en un certificado específico.
El problema de la verificación estándar es que cualquiera de las cientos de CA raíz puede emitir un certificado válido para su dominio — accidentalmente o bajo coacción. Un atacante que obtiene acceso a un proxy corporativo con su propio certificado raíz puede realizar un ataque MITM sin advertencia del navegador. SSL Pinning cierra esta vulnerabilidad: incluso si una CA emite un certificado fraudulento, la aplicación lo rechazará porque la huella digital no coincide con la registrada.
En las aplicaciones móviles, SSL Pinning es especialmente importante porque los dispositivos a menudo operan en redes no seguras — Wi-Fi público, proxies corporativos con inspección de tráfico, puntos de acceso infectados. Según el Verizon Mobile Security Index (2025), más del 60% de las filtraciones de datos en aplicaciones móviles están relacionadas con la interceptación de tráfico en la capa de transporte.
Las aplicaciones móviles transmiten datos sensibles — tokens de autenticación, información de pago, datos personales de usuarios. Sin protección adicional, HTTPS puede verse comprometido mediante la sustitución del certificado raíz en el dispositivo — por ejemplo, después de instalar un perfil corporativo o una aplicación maliciosa. SSL Pinning garantiza que incluso si se instala una CA raíz fraudulenta en el dispositivo, la aplicación continuará verificando el certificado contra su propia lista blanca.
El proceso de SSL Pinning consta de tres etapas: captura de la huella digital, verificación en la conexión y manejo de errores. Durante el desarrollo, el ingeniero obtiene la huella digital SHA-256 del certificado del servidor (openssl x509 -fingerprint -sha256) y la incrusta en el código de la aplicación o archivo de configuración. Con cada solicitud HTTPS, la aplicación calcula la huella digital del certificado recibido y la compara con la almacenada — si los valores no coinciden, la conexión se termina.
La primera etapa es el pinning en tiempo de compilación: el desarrollador conoce los certificados del servidor de antemano e incrusta sus hashes. La segunda etapa es el pinning en la primera conexión (trust on first use, TOFU): la aplicación recuerda el certificado en la primera solicitud y lo usa para verificar todas las siguientes. TOFU es conveniente para entornos dinámicos pero es vulnerable en el primer ataque — si la primera conexión ya está interceptada, el certificado fraudulento será aceptado como de confianza.
Un detalle crítico son los backup pins. Los certificados tienen una fecha de vencimiento, y cuando se reemplazan, la aplicación sin actualización perderá la conexión con el servidor. Los ingenieros incluyen 2–3 huellas digitales adicionales — por ejemplo, la huella digital de un certificado de respaldo y la huella digital de la CA raíz. Si el certificado principal cambia, la aplicación verifica contra los backup pins y la conexión continúa funcionando.
# Obtención de la huella digital SHA-256 del certificado
openssl s_client -connect example.com:443 </dev/null 2>/dev/null | \
openssl x509 -pubkey -noout | \
openssl pkey -pubin -outform der | \
openssl dgst -sha256 -binary | \
base64
Existen dos enfoques principales para implementar el pinning: fijación al certificado completo (certificate pinning) y fijación a la clave pública (public key pinning). Cada enfoque tiene sus propias fortalezas y limitaciones que afectan la seguridad y el mantenimiento.
| Tipo | Objeto de fijación | Flexibilidad | Seguridad |
|---|---|---|---|
| Certificate Pinning | Certificado X.509 completo | Baja — requiere actualización cuando cambia el certificado | Alta — fijación precisa |
| Public Key Pinning | Clave pública del certificado | Media — la clave puede estar en un nuevo certificado | Alta — menos sensible a los detalles del certificado |
| Hash Pinning | Hash SHA-256 del certificado o clave | Alta — se pueden cambiar certificados sin cambiar la clave | Media — depende de la fortaleza del hash |
La fijación de certificado es el método más estricto. La aplicación almacena una copia del certificado de confianza o su huella digital SHA-256 y la compara con el certificado del servidor en cada conexión HTTPS. Este método proporciona la máxima seguridad pero crea problemas durante la rotación — los certificados suelen durar 1–2 años, después de lo cual se requiere una actualización forzada de la aplicación. Recomendado para sistemas críticos con un ciclo de actualización controlado.
La fijación de clave pública es un enfoque más flexible. En lugar de todo el certificado, la aplicación recuerda solo la clave pública RSA o ECDSA del servidor. La clave puede permanecer sin cambios cuando se reemite el certificado, si la empresa usa el mismo par de claves. Esto reduce la frecuencia de las actualizaciones de la aplicación. Sin embargo, si la clave se ve comprometida, se requerirá un reemplazo en cascada en todos los clientes.
En la plataforma Apple, SSL Pinning se implementa a través del delegado de URLSession. El desarrollador crea una clase que implementa el protocolo URLSessionDelegate y sobrescribe el método didReceive challenge, donde verifica manualmente el certificado del servidor contra las huellas digitales almacenadas. Un enfoque alternativo es usar Alamofire con ServerTrustManager, que simplifica la configuración.
class SSLPinningDelegate: NSObject, URLSessionDelegate {
let pinnedHash = "sha256/Wi24BE7j5qLk0iLvPq6ePEsVRqZ1yW0F6wLg="
func urlSession(_ session: URLSession,
didReceive challenge: URLAuthenticationChallenge,
completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
guard let serverTrust = challenge.protectionSpace.serverTrust
else { return completionHandler(.cancelAuthenticationChallenge, nil) }
if validate(serverTrust, pinnedHash) {
completionHandler(.useCredential, URLCredential(trust: serverTrust))
} else {
completionHandler(.cancelAuthenticationChallenge, nil)
}
}
}
En el ejemplo, el delegado recibe una solicitud de autenticación de URLSession, extrae serverTrust del challenge y compara la huella digital SHA-256 del certificado con la almacenada. Si la huella digital coincide — la conexión continúa, de lo contrario se rechaza el challenge. Para producción, vale la pena agregar verificación de múltiples backup pins y registro de errores para monitoreo.
A partir de iOS 14, Apple agregó soporte integrado para Certificate Pinning a través de Info.plist. El desarrollador especifica los certificados de confianza en la clave NSAppTransportSecurity con el sub-diccionario NSPinnedDomains. Este enfoque no requiere escribir código pero es menos flexible — es imposible cambiar dinámicamente los pins o registrar errores de verificación.
En Android, existen tres formas principales de implementar SSL Pinning: a través de CertificatePinner de la biblioteca OkHttp, a través de Network Security Config en XML, y mediante verificación personalizada en HttpsURLConnection. OkHttp es el enfoque más popular y recomendado, utilizado en Retrofit y otros clientes HTTP.
val certificatePinner = CertificatePinner.Builder()
.add("api.example.com",
"sha256/Wi24BE7j5qLk0iLvPq6ePEsVRqZ1yW0F6wLg=")
.add("api.example.com",
"sha256/FiPq6ePEsVRqZ1yW0F6wLgWi24BE7j5qLk0iL=") // backup pin
.build()
val client = OkHttpClient.Builder()
.certificatePinner(certificatePinner)
.build()
En la configuración de OkHttp, el desarrollador especifica el dominio y una o más huellas digitales SHA-256. En la primera huella digital, OkHttp compara el certificado del servidor con los pins especificados. Si no hay coincidencia, el cliente lanza SSLPeerUnverifiedException. Un backup pin es obligatorio — sin él, cuando el certificado cambia, las solicitudes a la API comenzarán a fallar inmediatamente.
Android admite Certificate Pinning declarativo a través de configuración XML desde API 24. El archivo res/xml/network_security_config.xml contiene una lista de dominios y sus huellas digitales. Este método es conveniente para configuraciones estáticas pero no permite implementar TOFU o lógica de verificación personalizada con registro de anomalías.
<!-- res/xml/network_security_config.xml -->
<network-security-config>
<domain-config cleartextTrafficPermitted="false">
<domain includeSubdomains="true">api.example.com</domain>
<pin-set expiration="2027-12-31">
<pin digest="SHA-256">
Wi24BE7j5qLk0iLvPq6ePEsVRqZ1yW0F6wLg=</pin>
<pin digest="SHA-256">
FiPq6ePEsVRqZ1yW0F6wLgWi24BE7j5qLk0iL=</pin>
</pin-set>
</domain-config>
</network-security-config>
SSL Pinning aumenta significativamente la seguridad de una aplicación móvil pero introduce complejidades operativas. La principal ventaja es la protección contra ataques MITM incluso cuando las CA raíz están comprometidas. La aplicación confía solo en aquellos certificados explícitamente especificados por el desarrollador, no en toda la infraestructura de autoridades de certificación públicas. Esto es especialmente crítico para aplicaciones financieras, mensajeros y aplicaciones con datos sensibles.
El principal inconveniente es la complejidad de la rotación de certificados. Si un certificado caduca o se revoca, los usuarios sin actualización de la aplicación pierden la conexión. Esto se resuelve mediante backup pins y un mecanismo de actualización gradual: la nueva aplicación conoce tanto los certificados antiguos como los nuevos, y después de una actualización completa de los usuarios, el pin antiguo se elimina del código. Se recomienda incluir al menos 2 backup pins — uno para el certificado actual, uno para el futuro.
Otro compromiso es la imposibilidad de usar proxies públicos para depuración de tráfico (Charles Proxy, Burp Suite) sin deshabilitar el pinning. Esto complica la depuración de solicitudes de red durante el desarrollo. La solución es la compilación condicional: el pinning está deshabilitado en las compilaciones de debug y habilitado en las de release. OWASP recomienda usar el indicador BuildConfig.DEBUG para el cambio.
| Aspecto | Ventaja | Desventaja |
|---|---|---|
| Seguridad | Protección contra MITM a través de CA fraudulentas | Complejidad cuando una clave se ve comprometida |
| Mantenimiento | Control explícito de confianza | La rotación requiere actualización de la aplicación |
| Depuración | Conexión garantizada con el servidor correcto | Bloquea los proxies de depuración |
Preguntas frecuentes
La verificación HTTPS estándar confía en cualquier certificado firmado por una CA raíz conocida. SSL Pinning confía solo en un certificado específico o clave — si una CA emite un certificado fraudulento, la aplicación lo rechazará.
Los certificados suelen durar 1–2 años. Se recomienda actualizar los pins 3–6 meses antes de que expire el certificado actual, agregando la nueva huella digital como backup pin, y eliminando la antigua después de la rotación.
Sí, pero hay que tener en cuenta que las CDN pueden cambiar los certificados al cambiar entre servidores edge. Se recomienda fijarse a la clave pública en lugar de a un certificado específico, y usar múltiples backup pins.
La conexión se termina con un error — en Android es SSLPeerUnverifiedException, en iOS el challenge se rechaza con .cancelAuthenticationChallenge. La aplicación debe manejar correctamente este error y notificar al usuario.
No, pero OWASP lo recomienda para aplicaciones que manejan datos sensibles: banca, salud, sistemas corporativos. Para aplicaciones simples de solo lectura, la verificación HTTPS estándar con certificados EV suele ser suficiente.
Resumen
Desarrollaremos una aplicación móvil llave en mano
IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.
Lea también