使用mssql-python的加密与TLS

mssql-python驱动支持通过传输层安全(TLS)加密连接。 加密保护了您的应用程序与SQL Server之间传输的数据,防止窃听和中间攻击。

连接加密

启用加密功能

使用 Encrypt 关键字来控制连接加密:

import mssql_python

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

加密关键词值

价值 描述
yes 需要加密,如果服务器不支持TLS就会失败。
no 不会加密连接。 不建议用于生产。
strict 采用TDS 8.0严格加密模式。 需要 SQL Server 2022 或更高版本。

Important

Azure SQL 数据库 需要 Encrypt=yes. 未加密的连接被拒绝。

证书验证

TrustServerCertificate(信任服务器证书)

控制驱动程序是否验证服务器的TLS证书:

# 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;"
)
价值 描述
no 验证证书与受信任CA的匹配。 这个数值是默认且推荐的设置。
yes 信任任何证书,跳过验证。 这个环境很不安全。

注意

在生产环境中设置 TrustServerCertificate=yes 会使你的应用面临中间人攻击。 只有在自签名证书的开发时才使用此设置。

TDS 8.0 严格加密

SQL Server 2022及更高版本支持TDS 8.0,采用严格加密模式:

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

严格模式提供最高的安全级别:

  • 驱动程序在进行任何 TDS 握手之前建立 TLS 连接。
  • 需要验证证书,而且不能使用 TrustServerCertificate=yes
  • 该模式提供最高级别的拦截防护。

证书中的主机名

当服务器的证书名称与连接服务器名称不匹配时:

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

该关键词在以下情况下非常有用:

  • 你的应用通过IP地址连接,而不是主机名。
  • 服务器位于负载均衡器后端。
  • 证书使用与连接服务器名称不同的主题名称。

Azure SQL 数据库

Azure SQL 数据库 需要加密:

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

本地部署的 SQL Server(生产环境)

对于带有CA签名证书的本地SQL Server,驱动程序验证服务器身份时保持TrustServerCertificate=no

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

使用自签名证书进行开发

在使用自签名证书开发过程中,设置 TrustServerCertificate=yes 跳过证书验证:

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

SQL Server 2022 及更高版本中的严格模式

对于 TDS 8.0,请使用 Encrypt=strict,它会从一开始就使用 TLS 对整个连接进行封装:

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

Troubleshooting

“SSL 提供者:证书验证失败”

服务器证书无法验证。 进行以下检查:

  • 确认证书来自可信的CA。
  • 检查证书的有效期是否有效。
  • 确认服务器主机名与证书CN或SAN一致。
  • 对于开发,请使用 TrustServerCertificate=yes

“TCP提供商:现有连接被强制关闭”

服务器可能需要加密,但客户端没有请求加密。 请尝试以下步骤:

  • Encrypt=yes 添加到你的连接字符串中。
  • 检查SQL Server配置中的强制加密设置。

“证书链是由不值得信赖的权威机构发出的”

证书的根CA不在系统的可信根存储中。 进行以下检查:

  • 将CA证书安装到受信任的根存储中。
  • 对于Azure SQL,确保你的系统信任Microsoft的CA证书。
  • 对于开发,请使用 TrustServerCertificate=yes

严格加密时连接失败

TDS 8.0严格模式有以下要求:

  • 服务器必须运行 SQL Server 2022 或更高版本。
  • 服务器必须拥有有效且可信的证书。
  • 你无法设置 TrustServerCertificate=yes

如果服务器不支持 TDS 8.0,请改用 Encrypt=yes