Cifrado y TLS con mssql-python

El controlador mssql-python soporta conexiones cifradas a través de la Seguridad de la Capa de Transporte (TLS). El cifrado protege los datos en tránsito entre tu aplicación y SQL Server, y previene escuchas ocultas y ataques de adversario en el medio.

Cifrado de la conexión

Habilitación del cifrado

Utiliza la Encrypt palabra clave para controlar el cifrado de la conexión:

import mssql_python

# Require encryption (recommended)
conn = mssql_python.connect(
    "Server=<server>.database.windows.net;"
    "Database=<database>;"
    "Authentication=ActiveDirectoryDefault;"
    "Encrypt=yes;"
)

Cifrar valores de palabras clave

Valor Descripción
yes Requiere cifrado y falla si el servidor no soporta TLS.
no No cifra la conexión. No se recomienda para el entorno de producción.
strict Utiliza el modo de cifrado estricto TDS 8.0. Requiere SQL Server 2022 o posterior.

Importante

Azure SQL Database requiere Encrypt=yes. Las conexiones sin cifrado son rechazadas.

Validación de certificados

TrustServerCertificate

Controla si el controlador valida el certificado TLS del servidor:

# Validate server certificate (recommended for production)
conn = mssql_python.connect(
    "Server=<server>.database.windows.net;"
    "Database=<database>;"
    "Encrypt=yes;"
    "TrustServerCertificate=no;"
)

# Skip certificate validation (development only)
conn = mssql_python.connect(
    "Server=<server>;"
    "Database=<database>;"
    "Authentication=ActiveDirectoryDefault;"
    "Encrypt=yes;"
    "TrustServerCertificate=yes;"
)
Valor Descripción
no Valida el certificado frente a las CAs de confianza. Este valor es la configuración predeterminada y recomendada.
yes Confía en cualquier certificado y omite la validación. Este entorno es inseguro.

Caution

Configurar TrustServerCertificate=yes en producción expone tu aplicación a ataques de intermediario malintencionado. Usa esta configuración solo para desarrollo con certificados firmados por ti mismo.

Cifrado estricto TDS 8.0

SQL Server 2022 y posteriores soportan TDS 8.0 con modo de cifrado estricto:

conn = mssql_python.connect(
    "Server=<server>.database.windows.net;"
    "Database=<database>;"
    "Encrypt=strict;"
)

El modo estricto proporciona el nivel de seguridad más alto:

  • El controlador establece TLS antes de realizar cualquier intercambio inicial de TDS.
  • Se requiere validación de certificados y no puedes usar TrustServerCertificate=yes.
  • Este modo proporciona el mayor nivel de protección contra la intercepción.

HostNameInCertificate

Cuando el nombre del certificado del servidor no coincide con el nombre del servidor de conexión:

conn = mssql_python.connect(
    "Server=192.168.1.100;"  # IP address
    "Database=<database>;"
    "Encrypt=yes;"
    "TrustServerCertificate=no;"
    "HostNameInCertificate=<server>.contoso.com;"  # Certificate CN
)

Esta palabra clave es útil cuando:

  • Tu aplicación se conecta a través de una dirección IP en lugar de un nombre de host.
  • El servidor está detrás de un balanceador de carga.
  • El certificado utiliza un nombre de sujeto diferente al nombre del servidor de conexión.

Azure SQL Database

Azure SQL Database requiere cifrado:

conn = mssql_python.connect(
    "Server=<server>.database.windows.net;"
    "Database=<database>;"
    "Authentication=ActiveDirectoryDefault;"
    "Encrypt=yes;"
    "TrustServerCertificate=no;"
)

SQL Server local (producción)

Para un SQL Server local con un certificado firmado por una CA, mantén TrustServerCertificate=no para que el controlador valide la identidad del servidor:

conn = mssql_python.connect(
    "Server=<server>;"
    "Database=<database>;"
    "Authentication=ActiveDirectoryDefault;"
    "Encrypt=yes;"
    "TrustServerCertificate=no;"
)

Desarrollo con certificados autofirmados

Durante el desarrollo con certificados autofirmados, configurado TrustServerCertificate=yes para saltarse la validación de certificados:

conn = mssql_python.connect(
    "Server=localhost;"
    "Database=<database>;"
    "Authentication=ActiveDirectoryDefault;"
    "Encrypt=yes;"
    "TrustServerCertificate=yes;"
)

SQL Server 2022 y versiones posteriores con modo estricto

Úsalo Encrypt=strict para TDS 8.0, que envuelve toda la conexión en TLS desde el principio:

conn = mssql_python.connect(
    "Server=<server>;"
    "Database=<database>;"
    "Encrypt=strict;"
)

Troubleshooting

"Proveedor SSL: Fallo en la validación de certificados"

El certificado del servidor no pudo ser validado. Haz estas comprobaciones:

  • Verifica que el certificado sea de una CA de confianza.
  • Comprueba que la fecha de caducidad del certificado sea válida.
  • Verifica que el nombre de host del servidor coincida con el certificado CN o SAN.
  • Para el desarrollo, use TrustServerCertificate=yes.

"Proveedor TCP: Una conexión existente fue cerrada por la fuerza"

El servidor puede requerir cifrado, pero el cliente no lo solicitó. Pruebe estos pasos:

  • Añade Encrypt=yes a tu cadena de conexión.
  • Consulta la configuración de SQL Server para la configuración de Force Encryption.

"La cadena de certificados fue emitida por una autoridad que no es de confianza"

La CA raíz del certificado no está en el almacén raíz confiable del sistema. Haz estas comprobaciones:

  • Instala el certificado de la CA en la tienda raíz de confianza.
  • Para Azure SQL, asegúrate de que tu sistema confíe en los certificados de CA de Microsoft.
  • Para el desarrollo, use TrustServerCertificate=yes.

La conexión falla con cifrado estricto

El modo estricto TDS 8.0 tiene estos requisitos:

  • El servidor debe ejecutar SQL Server 2022 o posterior.
  • El servidor debe tener un certificado válido y de confianza.
  • No puedes configurar TrustServerCertificate=yes.

Si el servidor no soporta TDS 8.0, usa Encrypt=yes en su lugar.