Error: The handshake failed due to an unexpected packet format.

Protocolo TLS1.1/1.2

Posted by Juan Valera on Thursday, September 8, 2016

¿Qué es TLS?

El protocolo TLS (Transport Layer Security o seguridad en capas de transporte) es un protocolo criptográfico que se encarga de garantizar las comunicaciones en Internet.

El TLS es la siguiente generación del Certificado SSL, permite y garantiza el intercambio de datos en un entorno seguro y privado entre el usuario y el servidor, mediante : HTTP, POP3, IMAP, SSH, SMTP o NNTP. Nos referimos al TLS como la evolución del SSL dado que está basado en éste último certificado y funciona de manera muy similar, básicamente encripta la información compartida.

¿Cómo la funciona el protocolo TLS?

El TLS funciona a través de dos protocolos en capas diferentes. El protocolo de autenticación llamado TLS Record Protocol y el de mútuo acuerdo llamado TLS Handshake Protocol.

  1. TLS Record Protocol - Lleva a cabo la autenticación para la transmisión de datos, mediante una conexión privada y fiable (encriptación e integridad del emisor-receptor).
  2. TLS Handshake Protocol - Negocia el mensaje de manera segura. En cada mensaje se especifica el protocolo en el content_type, luego se cifra y por último se empaqueta con un código de autentificación o MAC.

El protocolo TLS se distingue por la seguridad con la interoperabilidad (las transmisiones de datos encriptados de diferentes aplicaciones como HTTP, que pasa a ser HTTPS).

Se puede decir entonces que protocolo TLS, se lleva a cabo a través de un canal seguro (cifrado) entre cliente y servidor, en donde se realiza el convenio de criptografía del mensaje, se autentifican las claves del cifrado y se realiza la transmisión segura.

El problema

Se realiza el Request al API:

                        
                                
Response response = new Response();
WebClient wc = new WebClient();
.
.
.
byte[] responseData = wc.UploadValues(API_URL, form);

Al realizar el Request se generaba el error de servidor:

The handshake failed due to an unexpected packet format.

Si recordamos el TLS Handshake Protocol es el que se encarga de negociar el mensaje de manera segura, por eso podemos inferir que el TLS puede ser distinto al esperado (en .NET por defecto es TLS/1.0).

Para ver la comunicación https, podemos utilizar Fiddler . Al analizar el web response en Fiddler, vemos que se utiliza TLS 1.2 .

La solución

Con el fin de utilizar TLS 1.1 o TLS 1.2 en .NET, tenemos que establecer SecurityProtocol antes de cualquier llamada WebClient agregando la siguiente linea de codigo:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

                        
                                
Response response = new Response();
WebClient wc = new WebClient();
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
.
.
.
byte[] responseData = wc.UploadValues(API_URL, form);

Espero que este post les sirva de ayuda.

Cualquier comentario o duda pueden contactarme a través de la sección Contact.

Juan Valera.