Microsoft.Data.SqlClient 中的加密和憑證驗證

下載 ADO.NET

使用傳輸層安全(TLS)來加密應用程式與 SQL Server 之間的流量。 保持伺服器憑證驗證啟用以驗證伺服器身份。 沒有身份驗證的加密無法防止冒充伺服器的 中間 攻擊者。

Microsoft。Data.SqlClient 預設為 Encrypt=Mandatory 和 TrustServerCertificate=false。 Encrypt=true 與 Mandatory同義。 對於遠端連線,請明確請求這些設定,並配置一個伺服器憑證,讓用戶端可以驗證:

Server=tcp:<server>,1433;Database=<database>;Integrated Security=true;Encrypt=true;TrustServerCertificate=false;MultiSubnetFailover=true;

替換佔位符,並使用伺服器和應用程式環境支援的 認證方法 。 關於Microsoft Fabric中的Azure SQL或 SQL 資料庫,請參見Microsoft Entra認證。

選擇加密模式

Encrypt 控制用戶端是否需要加密。 伺服器也可能需要加密。 下表描述了未進行憑證釘選的當前行為:

用戶端設定 伺服器需求 憑證驗證 結果
Encrypt=Optional 或 false 不會強制加密。 都不是,無論 TrustServerCertificate。 只有登入封包是加密的。 後續的流量則沒有加密。
Encrypt=Optional;TrustServerCertificate=false 強制加密。 信任鏈、有效性和伺服器名稱。 所有流量都已加密。 無效憑證會導致連線失敗。
Encrypt=Optional;TrustServerCertificate=true 強制加密。 被繞過了。 所有流量都被加密,但伺服器的身份並未被驗證。
Encrypt=Mandatory;TrustServerCertificate=false 任一種設定。 信任鏈、有效性和伺服器名稱。 所有流量都已加密。 無效憑證會導致連線失敗。
Encrypt=Mandatory;TrustServerCertificate=true 任一設定皆可。 被繞過了。 所有流量都被加密,但伺服器的身份並未被驗證。
Encrypt=Strict 支援表格式資料流(TDS)8.0。 Required. TrustServerCertificate 無法繞過它。 TLS 會先於 TDS 訊息開始。 不支援的伺服器或無效憑證會導致連線失敗。

使用 Mandatory 連線至不支援 TDS 8.0 的伺服器時,請使用加密連線。 請在支援 TDS 8.0 的端點,包括 SQL Server 2022(16.x)及更新版本時使用Strict。 TDS 8.0 支援 TLS 1.2 和 TLS 1.3;它不需要 TLS 1.3。 協商後的 TLS 版本也取決於用戶端、伺服器和作業系統的設定。

Optional 不是用來解決憑證錯誤的方法。 當伺服器不需要加密時,應用程式資料可能會保持未加密。

配置可驗證的伺服器憑證

一般的憑證驗證:

  1. 配置符合 SQL Server 憑證要求的憑證。
  2. 請在憑證的主體替代名稱(SAN)中包含客戶用來連接的名稱。
  3. 讓發行憑證授權中心及任何必要的中介憑證對每個用戶端主機或容器都被信任。
  4. 將 SQL Server 設定為使用該憑證,並在用戶端保留 TrustServerCertificate=false。
  5. 計畫證書到期前的續期,包括名稱或核發機關的任何變更。

來自公共或企業證書授權機構的證書可以滿足這些要求。 企業憑證在 Linux 容器或獨立開發者電腦上不會自動被信任。

透過別名連接

如果連線使用的網域名稱系統(DNS)別名不在憑證中,請先考慮發行包含該別名的憑證。 或者,也可以設定 HostNameInCertificate 為憑證中預期的名稱:

Server=tcp:sql-alias.contoso.com,1433;Database=<database>;Integrated Security=true;Encrypt=true;TrustServerCertificate=false;HostNameInCertificate=sql-server.contoso.com;MultiSubnetFailover=true;

HostNameInCertificate 更改 SqlClient 在憑證驗證時所期望的名稱。 它不會改變網路目的地,也不會繞過信任鏈和到期檢查。 當伺服器名稱已經和證書相符時,保持不設定。

釘選特定的伺服器憑證

ServerCertificate 提供本地憑證檔案,以便與伺服器的憑證精確比較。 支援的格式包括 Privacy-Enhanced Mail(PEM)和可辨識編碼規則(DER),其中包括 .cer 憑證檔案。 將它與 Encrypt=Mandatory 或 Encrypt=Strict 搭配使用,並保留 TrustServerCertificate=false。

Server=tcp:<server>,1433;Database=<database>;Integrated Security=true;Encrypt=Strict;TrustServerCertificate=false;ServerCertificate=C:\certificates\sql-server.cer;MultiSubnetFailover=true;

透過受信任的通道分發預期的憑證,並保護檔案免於被替換。 精確的憑證匹配是一般鏈與名稱驗證的替代方案,而非額外的檢查。 憑證位元組必須相符;僅有相同的主體名稱或公鑰是不夠的。 缺少、無法讀取、無效或不相符的腳位檔案,將無法通過驗證。

釘選將客戶端部署與憑證輪替結合。 當伺服器憑證變更(包括續約)時,更新 PIN 碼。 不要藉由接受來自網路且未經驗證的憑證來取得 PIN 碼。

SqlClient 不會公開回調給任意的 TLS 伺服器憑證驗證。 AccessTokenCallback 控制的是認證令牌的取得,而非 TLS 驗證。

開發證書與故障排除

使用可信的開發憑證並附上正確的伺服器名稱。 如果你在隔離的開發環境中暫時將 TrustServerCertificate=true 與 Encrypt=true 搭配使用,連線會經過加密,但用戶端不會驗證伺服器憑證。

警告

不要將 TrustServerCertificate=true 作為正式環境中修正憑證錯誤的方式來部署。 它會禁用伺服器 Mandatory 身份驗證,且對 Strict沒有影響。

Failure 檢查
憑證鏈不被信任。 在用戶端安裝適當的受信任根憑證和中繼憑證。 確認 SQL Server 實際顯示的憑證。
證書名稱不符。 將 Server 與憑證 SAN 進行比較。 更正名稱、憑證或刻意設定的 HostNameInCertificate 覆寫。
證書已過期。 更新伺服器憑證並檢查客戶端時鐘。
置頂的憑證不匹配或無法載入。 檢查檔案路徑、權限、格式和部署憑證。 透過你信任的分發流程更新 PIN 碼。
嚴格加密無法連線。 確認該端點支援 TDS 8.0,且其 TLS 設定是否與用戶端相容。

關於伺服器端設定,請參見 憑證總覽。

加密和憑證驗證行為中的變更

這些相容性說明說明升級舊應用程式時的行為變化。 新應用程式應使用本文所述的現有設定。

驅動程式釋出 變更
1.0 Encrypt=false 是預設值。 當客戶端不請求加密時,伺服器強制加密不會觸發憑證驗證。
2.0 伺服器強制加密即使在 Encrypt=false 時也會遵循 TrustServerCertificate。
4.0 加密會預設啟用。 升級可能會暴露先前未被察覺的憑證設定錯誤。
5.0 新增 Optional、Mandatory、Strict 和 HostNameInCertificate。
5.1 新增用於憑證釘選的 ServerCertificate。
7.0.3 修正了管理網路憑證驗證因檔案缺失、無效或不匹配而關閉的故障,即使一般平台驗證成功。