¡Hola Pablo Diez!
Bienvenido a Microsoft Q&A.
Parece que estás enfrentando un problema común al trabajar con Schannel y TLS en C. Y a la vez bastante específico, déjame intentar ayudarte con la información general que podamos compartir en un foro público.
Aquí hay algunas cosas que podrías verificar para solucionar el error SEC_E_DECRYPT_FAILURE
:
Verifica los encabezados y la longitud de los datos cifrados:
- Asegúrate de que los datos cifrados que estás recibiendo tienen el formato correcto y la longitud esperada. Los encabezados que mencionas parecen correctos, pero verifica que los datos no estén truncados o corruptos.
Alineación de los buffers:
- Asegúrate de que los buffers que estás utilizando para
DecryptMessage
estén correctamente alineados y configurados. LosSecBuffer
deben estar correctamente inicializados y no deben contener datos adicionales que puedan interferir con el proceso de descifrado.
Revisa las versiones del protocolo TLS:
- Aunque mencionas que el servidor y el cliente están usando TLS 1.2, verifica que ambos lados estén configurados para usar la misma versión del protocolo y que no haya discrepancias en las configuraciones de seguridad.
Certificados y claves:
- Dado que estás usando un certificado autofirmado, asegúrate de que el cliente confíe en el certificado del servidor. Aunque mencionas que
InitializeSecurityContext
no da error deSEC_E_UNTRUSTED_ROOT
, verifica que no haya otros problemas con el certificado.
Depuración adicional:
- Agrega más mensajes de depuración para verificar el estado de los contextos de seguridad (
hContext
) y los atributos de conexión (SecPkgContext_ConnectionInfo
). Esto puede ayudarte a identificar si hay algún problema con la configuración del contexto. Aquí tienes un ejemplo de cómo podrías ajustar tu código para agregar más mensajes de depuración y verificar los buffers:
SecPkgContext_ConnectionInfo connInfo;
if (QueryContextAttributes(&hContext, SECPKG_ATTR_CONNECTION_INFO, &connInfo) == SEC_E_OK) {
printf("TLS protocol: %u\n", connInfo.dwProtocol); // Debe ser TLS 1.2 o 1.3
} else {
printf("Failed to query context attributes\n");
}
char encryptedData[4096]; // Buffer para los datos cifrados
SecBuffer InBuffers[4];
SecBufferDesc InBuffer;
// Recibir datos cifrados desde el servidor
int bytesReceived = recv(conn, encryptedData, sizeof(encryptedData), 0);
if (bytesReceived <= 0) {
printf("recv failed or connection closed\n");
return SOCKET_ERROR;
}
printf("Encrypted data (hex): ");
for (int i = 0; i < bytesReceived; i++) {
printf("%02x ", (unsigned char)encryptedData[i]);
}
printf("\n");
InBuffers[0].pvBuffer = encryptedData;
InBuffers[0].cbBuffer = bytesReceived;
InBuffers[0].BufferType = SECBUFFER_DATA;
InBuffers[1].BufferType = SECBUFFER_EMPTY;
InBuffers[2].BufferType = SECBUFFER_EMPTY;
InBuffers[3].BufferType = SECBUFFER_EMPTY;
InBuffer.cBuffers = ARRAYSIZE(InBuffers);
InBuffer.pBuffers = InBuffers;
InBuffer.ulVersion = SECBUFFER_VERSION;
SECURITY_STATUS secStatus = DecryptMessage(hContext, &InBuffer, 0, NULL);
if (secStatus != SEC_E_OK) {
printf("DecryptMessage failed with error code: 0x%x\n", secStatus); // No pasa de aquí
if (secStatus == SEC_E_CONTEXT_EXPIRED) {
printf("The context has expired. Re-handshake may be needed.\n");
}
return SOCKET_ERROR;
}
// Si el descifrado es exitoso, procesa los datos descifrados aquí
Espero que estos consejos ayuden a resolver el problema. Si necesitas más asistencia, estoy a tu disposición.
Saludos,
Jonathan.
----------*
Tu opinión es muy importante para nosotros! Si esta respuesta resolvió tu consulta, por favor haz clic en 'SÍ'. Esto nos ayuda a mejorar continuamente la calidad y relevancia de nuestras soluciones.