使用 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 Database 需要 Encrypt=yes. 未加密的連線會被拒絕。

憑證驗證

信任伺服器證書

控制驅動程式是否驗證伺服器的 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 信任任何憑證,跳過驗證程序。 這個環境很不安全。

Caution

在生產環境中設定 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 Database

Azure SQL Database 需要加密:

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