.NET Framework 的傳輸層安全性 (TLS) 最佳做法
注意
此頁面包含 .NET Framework TLS 資訊。 如果您要尋找 .NET TLS 資訊,請參閱:TLS/SSL 最佳做法
.NET Framework 支援使用傳輸層安全性 (TLS) 通訊協定來確保網路通訊的安全性。
什麼是傳輸層安全性 (TLS)?
警告
TLS 1.0 和 1.1 已被 RFC8996 取代。 此文件僅涵蓋 TLS 1.2 和 TLS 1.3。
傳輸層安全性 (TLS) 通訊協定為一項業界標準的最新版本,其設計目的是用來協助保護透過網際網路所通訊之資訊的隱私權。 TLS 1.3 是可提供優於先前版本之安全性的標準。 本文提供保護使用 TLS 通訊協定之 .NET Framework 應用程式的建議。
誰會受益於此文件?
- 直接使用 System.Net API (例如,System.Net.Http.HttpClient 和 System.Net.Security.SslStream) 的開發人員。
- 直接使用運用 System.ServiceModel 命名空間之 WCF 用戶端和服務的開發人員。
.NET Framework 中的 TLS 支援
由於 .NET Framework 相依於 Windows 上的 Schannel
,因此可以交涉和使用的版本取決於作業系統。
以下是更新的範例資料表,其中顯示不同作業系統版本和 .NET Framework 目標版本組合所支援的最高 TLS 版本:
.NET Framework 目標版本 | Windows 10 | Windows 11 |
---|---|---|
3.5 | TLS 1.2 | TLS 1.2 |
4.6.2 | TLS 1.2 | TLS 1.3 |
4.7 | TLS 1.2 | TLS 1.3 |
4.7.1 | TLS 1.2 | TLS 1.3 |
4.7.2 | TLS 1.2 | TLS 1.3 |
4.8 | TLS 1.2 | TLS 1.3 |
4.8.1 | TLS 1.2 | TLS 1.3 |
如需詳細資訊,請參閱 Schannel 中的 TLS 通訊協定版本支援。
建議
- 針對 TLS 1.3,以 .NET Framework 4.8 或更新版本為目標。 查看稽核您的程式碼一節,了解如何驗證您的
target framework
。 - 請勿明確指定 TLS 版本,亦即不要使用採用明確
SslProtocols
參數的SslStream
方法多載。- 如此一來,您的程式碼會讓 OS 決定 TLS 版本。
- 如果您必須設定 ServicePointManager.SecurityProtocol,請將其設定為 SecurityProtocolType.SystemDefault。 這也會使用 OS 預設值。
- 如果您必須使用採用明確
SslProtocols
參數的SslStream
方法多載,請將SslProtocols.SystemDefault
作為引數傳遞。 這也會使用 OS 預設值。
- 執行完整的程式碼稽核,以確認您沒有明確指定 TLS 或 SSL 版本。
警告
請勿使用 SslProtocols.Default
,因為其會將 TLS 版本設定為已過時的 SSL3 和 TLS 1.0。
當應用程式讓 OS 選擇 TLS 版本時:
- 其會自動運用於未來新增的新 TLS 通訊協定。
- OS 會封鎖被發現不安全的通訊協定 (例如 SSL3 和 TLS 1.0)。
本文說明如何針對應用程式所執行的.NET Framework 版本,啟用可供使用的最強安全性。 當應用程式明確設定安全性通訊協定及版本時,它將會退出所有其他替代方案,並退出 .NET Framework 及 OS 預設行為。 如果您想讓應用程式能夠交涉 TLS 1.3 連線,明確設定至較低的 TLS 版本將會防止 TLS 1.3 連線。
如果您無法避免明確指定通訊協定版本,我們強烈建議您指定 TLS 1.2 或 TLS 1.3 (也就是 currently considered secure
)。 如需識別及移除 TLS 1.0 相依性的指引,請下載解決 TLS 1.0 問題白皮書。
在 .NET Framework 4.7 中,WCF 預設支援 TLS 1.2。 從 .NET Framework 4.7.1 開始,WCF 預設會使用作業系統所設定的版本。 如果有應用程式是搭配 SslProtocols.None
進行明確設定,WCF 在使用 NetTcp 傳輸時,便會使用作業系統的預設設定。
您可以在 GitHub 問題 .NET Framework 的傳輸層安全性 (TLS) 最佳做法 \(英文\) 中,詢問與本文件相關的問題。
對程式碼進行稽核並做出程式碼變更
針對 ASP.NET 應用程式,請檢查 web.config 的 <system.web><httpRuntime targetFramework>
元素,以確認您是使用正確的目標 .NET Framework 版本。
針對 Windows Forms 及其他應用程式,請參閱如何:將 .NET Framework 的某個版本設定為目標。
使用下列小節來確認您沒有使用特定的 TLS 或 SSL 版本。
若您必須明確設定安全性通訊協定
若您必須明確設定安全性通訊協定,而不是讓 .NET 或 OS 選擇安全性通訊協定,請選擇這些通訊協定:
- 針對 .NET Framework 3.5:TLS 1.2
- 針對 .NET framework 4.6.2 或更新版本:TLS 1.3
如果您在列舉中找不到指定的通訊協定,您可以將這些通訊協定新增為延伸模組檔案。 查看下面的內容:
SslProtocolExtensions.cs
namespace System.Security.Authentication
{
public static class SslProtocolsExtensions
{
// For .NET Framework 3.5
public const SslProtocols Tls12 = (SslProtocols)3072;
// For .NET Framework 4.6.2 and later
public const SslProtocols Tls13 = (SslProtocols)12288;
}
}
SecurityProtocolExtensions.cs
using System.Security.Authentication;
namespace System.Net
{
public static class SecurityProtocolTypeExtensions
{
// For .NET Framework 3.5
public const SecurityProtocolType Tls12 = (SecurityProtocolType)SslProtocolsExtensions.Tls12;
// For .NET Framework 4.6.2 and later
public const SecurityProtocolType Tls13 = (SecurityProtocolType)SslProtocolsExtensions.Tls13;
}
}
如需詳細資訊,請參閱針對 TLS 系統預設版本的支援已包含在 Windows 8.1 和 Windows Server 2012 R2 的 .NET Framework 3.5 中。
針對 System.Net API (HttpClient、SslStream)
若應用程式是以 .NET Framework 4.7 或更新版本作為目標
下列各節說明如何將您的應用程式設定為使用 TLS currently considered secure versions
。 (TLS 1.2、TLS 1.3)
針對 HttpClient 和 HttpWebRequest
使用 .NET Framework 4.7 和更新版本的 ServicePointManager 將使用 OS 中設定的預設安全性通訊協定。 若要在可能的情況下取得最佳的預設 OS 選擇,請不要為 ServicePointManager.SecurityProtocol 屬性設定值,其預設為 SecurityProtocolType.SystemDefault。
由於 SecurityProtocolType.SystemDefault 設定會導致 ServicePointManager 使用作業系統所設定的預設安全性通訊協定,根據應用程式執行所在的作業系統,您的應用程式的執行可能不同。 例如,Windows 10 使用 TLS 1.2,而 Windows 11 使用 TLS 1.3。
針對 SslStream
SslStream,在使用 .NET Framework 4.7 及更新版本的情況下,預設會讓 OS 選擇最佳的安全性通訊協定和版本。 若要在可能的情況下取得最佳的預設 OS 選擇,請不要使用會採用明確 SslProtocols 參數之 SslStream 的方法多載。 否則,請傳遞 SslProtocols.None。 建議您不要使用 Default;設定 SslProtocols.Default
會強制使用 SSL 3.0/TLS 1.0 並防止 TLS 1.2。
不要為 SecurityProtocol 屬性 (針對 HTTP 網路功能) 設定值。
不要使用會採用明確 SslProtocols 參數 (針對 TCP 通訊端網路功能) 之 SslStream 的方法多載。 當您將應用程式目標重新設為 .NET Framework 4.7 或更新版本時,即是遵循最佳做法建議。
針對 WCF 應用程式
若應用程式是以 .NET Framework 4.7 或更新版本作為目標
下列各節說明如何將您的應用程式設定為使用 TLS currently considered secure versions
。 (TLS 1.2、TLS 1.3)
使用搭配憑證認證使用傳輸安全性的 TCP 傳輸
WCF 會使用和其他 .NET Framework 相同的網路堆疊。
若您是以 4.7.1 為目標,WCF 預設便已設定為允許 OS 選擇最佳的安全性通訊協定,除非另外透過下列方式明確設定:
- 在您的應用程式組態檔中。
- 或在您應用程式的原始程式碼中。
根據預設,.NET Framework 4.7 及更新版本已設定為使用 TLS 1.2,並允許使用 TLS 1.1 或 TLS 1.0 的連線。 特過設定繫結以使用 SslProtocols.None,來設定 WCF 以允許 OS 選擇最佳的安全性通訊協定。 這可以在 SslProtocols 上設定。 SslProtocols.None
可以從 Transport 存取。 NetTcpSecurity.Transport
可以從 Security 存取。
若您是使用自訂繫結:
- 特過設定 SslProtocols 以使用 SslProtocols.None,來設定 WCF 以允許 OS 選擇最佳的安全性通訊協定。
- 或透過設定路徑
system.serviceModel/bindings/customBinding/binding/sslStreamSecurity:sslProtocols
來設定所使用的通訊協定。
若您沒有 使用自訂繫結,且您是使用設定來設定 WCF 繫結,請透過設定路徑 system.serviceModel/bindings/netTcpBinding/binding/security/transport:sslProtocols
來設定所使用的通訊協定。
使用具有憑證認證的訊息安全性
.NET Framework 4.7 及更新版本預設會使用於 SecurityProtocol 屬性中指定的通訊協定。 當 AppContextSwitch Switch.System.ServiceModel.DisableUsingServicePointManagerSecurityProtocols
設定為 true
時,WCF 會選擇最佳的通訊協定 (最高版本為 TLS 1.0)。
若應用程式是以 .NET Framework 4.7 之前的版本為目標
下列各節說明如何將您的應用程式設定為使用 TLS currently considered secure versions
。 (TLS 1.2、TLS 1.3)
使用搭配憑證認證使用 TCP 傳輸安全性的 .NET Framework 4.6.2
WCF 架構會自動選擇可用的最高版本通訊協定 (最高版本為 TLS 1.2),除非您明確設定通訊協定版本。 如需詳細資訊,請參閱先前的針對搭配憑證認證使用傳輸安全性的 WCF TCP 傳輸一節。
使用搭配憑證認證使用 TCP 傳輸安全性的 .NET Framework 3.5
這些版本的 WCF 架構明確指定使用 SSL 3.0 和 TLS 1.0 值。 這些值不能變更。 您必須更新並將目標重新設定為 NET Framework 4.6.2 或更新版本,以使用 TLS 1.2。
透過 AppContext 參數設定安全性 (適用於 .NET Framework 4.6.2 或更新版本)
只有在您的應用程式是以 .NET Framework 4.6.2 或更新版本為目標 (或是在其上執行) 的情況下,才會與描述於本節的 AppContext 參數具關連性。 無論是根據預設設定,或是透過明確設定這些參數,它們在可能的情況下都應為 false
。 若您想要透過其中一個或同時透過這兩個參數來設定安全性,請不要在程式碼中指定安全性通訊協定,因為這麼做將會覆寫這些參數。
針對 System.Net API (HttpClient、SslStream)
無論您是執行 HTTP 網路功能 (ServicePointManager) 或 TCP 通訊端網路功能 (SslStream),這些參數都具有相同的效果。
Switch.System.Net.DontEnableSchUseStrongCrypto
將 Switch.System.Net.DontEnableSchUseStrongCrypto
設定為 false
值,會導致您的應用程式使用強式加密。 將 DontEnableSchUseStrongCrypto
設定為 false
值,會使用更安全的網路通訊協定 (TLS 1.2 及 TLS 1.1),並封鎖不安全的通訊協定。 如需詳細資訊,請參閱 SCH_USE_STRONG_CRYPTO 旗標。 設定為 true
值會停用應用程式的強式加密。 此參數只會影響應用程式中的用戶端 (傳出) 連線。
若應用程式是以 .NET Framework 4.6.2 或更新版本作為目標,此參數預設會設定為 false
。 那是安全的預設值,也是我們建議的選項。 若您的應用程式是在 .NET Framework 4.6.2 上執行,但是以較舊的版本為目標,此參數預設會設定為 true
。 在此情況下,您應該明確地將它設定為 false
。
若您需要連線至不支援強式加密且無法升級的舊版服務,則 DontEnableSchUseStrongCrypto
應該僅設定為 true
值。
Switch.System.Net.DontEnableSystemDefaultTlsVersions
將 Switch.System.Net.DontEnableSystemDefaultTlsVersions
設為 false
值,會導致您的應用程式允許作業系統選擇通訊協定。 設定為 true
值會導致您的應用程式使用由 .NET Framework 所選取的通訊協定。
若應用程式是以 .NET Framework 4.7 或更新版本作為目標,此參數預設會設定為 false
。 這是建議的安全預設值。 若您的應用程式是在 .NET Framework 4.7 或更新版本上執行,但是以較舊的版本為目標,此參數預設會設定為 true
。 在此情況下,您應該明確地將它設定為 false
。
針對 WCF 應用程式
Switch.System.ServiceModel.DisableUsingServicePointManagerSecurityProtocols
將 Switch.System.ServiceModel.DisableUsingServicePointManagerSecurityProtocols
設定為 false
值,會導致您的應用程式針對使用憑證認證的訊息安全性,使用定義於 ServicePointManager.SecurityProtocols
中的值。 設定為 true
值會使用可用的最高版本通訊協定 (最高版本為 TLS1.0)
針對以 .NET Framework 4.7 及更新版本為目標的應用程式,此值預設會設定為 false
。 針對以 .NET Framework 4.6.2 及較舊版本為目標的應用程式,此值預設會設定為 true
。
Switch.System.ServiceModel.DontEnableSystemDefaultTlsVersions
將 Switch.System.ServiceModel.DontEnableSystemDefaultTlsVersions
設為 false
值,會設定預設設定以允許作業系統選擇通訊協定。 設定為 true
值會將預設值設定為可用的最高版本通訊協定 (最高版本為 TLS1.2)。
針對以 .NET Framework 4.7.1 及更新版本為目標的應用程式,此值預設會設定為 false
。 針對以 .NET Framework 4.7 及較舊版本為目標的應用程式,此值預設會設定為 true
。
如需 TLS 通訊協定的詳細資訊,請參閱風險降低:TLS 通訊協定。 如需 AppContext
參數的詳細資訊,請參閱 <AppContextSwitchOverrides> Element
。
透過 Windows 登錄來設定安全性
警告
設定登錄機碼會影響系統上的所有應用程式。 只有當您具有機器的完整控制權,並且可以控制登錄上的變更時,才使用此選項。
如果您無法設定其中一個 AppContext
參數 (或是兩個都無法設定),則可以透過本節中描述的 Windows 登錄機碼來控制應用程式所使用的安全性通訊協定。 如果您的應用程式是在 .NET Framework 3.5 上執行,或是無法編輯組態檔,便可能無法使用其中一個 AppContext
參數,或是兩個都無法使用。 若您想要透過登錄來設定安全性,請不要在程式碼中指定安全性通訊協定,因為這麼做將會覆寫這些登錄設定。
登錄機碼的名稱與相對應的 AppContext
參數類似,但名稱前方不會有 DontEnable
。 例如,AppContext
參數 DontEnableSchUseStrongCrypto
就是稱為 SchUseStrongCrypto 的登錄機碼。
這些機碼適用於所有 .NET Framework 版本。
無論您是執行 HTTP 網路功能 (ServicePointManager) 或 TCP 通訊端網路功能 (SslStream),下列所描述的登錄機碼都具有相同的效果。
SchUseStrongCrypto
HKEY_LOCAL_MACHINE\SOFTWARE\[Wow6432Node\]Microsoft\.NETFramework\<VERSION>: SchUseStrongCrypto
登錄輸入具有 DWORD 型別的值。 將值設為 1 會導致您的應用程式使用強式加密。 強式加密會使用更安全的網路通訊協定 (TLS 1.2 及 TLS 1.1),並封鎖不安全的通訊協定。 將值設為 0 會停用強式加密。 如需詳細資訊,請參閱 SCH_USE_STRONG_CRYPTO 旗標。 此登錄設定只會影響應用程式中的用戶端 (傳出) 連線。
若應用程式是以 .NET Framework 4.6 或更新版本作為目標,此機碼預設會設定為 1。 這是建議的安全預設值。 如果您的應用程式以 .NET Framework 4.5.2 或更早版本為目標,金鑰預設為 0。 在此情況下,您應該明確地將它的值設定為 1。
若您需要連線至不支援強式加密且無法升級的舊版服務,則此機碼的值應該僅設定為 0。
SystemDefaultTlsVersions
HKEY_LOCAL_MACHINE\SOFTWARE\[Wow6432Node\]Microsoft\.NETFramework\<VERSION>: SystemDefaultTlsVersions
登錄輸入具有 DWORD 型別的值。 將值設為 1 會導致您的應用程式允許作業系統選擇通訊協定。 將值設為 0 會導致您的應用程式使用由 .NET Framework 所選取的通訊協定。
<VERSION>
必須是 v4.0.30319 (針對 .NET Framework 4 及更新版本) 或 v2.0.50727 (針對 .NET Framework 3.5)。
若應用程式是以 .NET Framework 4.7 或更新版本作為目標,此機碼預設會設定為 1。 這是建議的安全預設值。 如果您的應用程式以 .NET Framework 4.6.1 或更早版本為目標,金鑰預設為 0。 在此情況下,您應該明確地將它的值設定為 1。
如需詳細資訊,請參閱 Windows 10 1511 版和 Windows Server 2016 Technical Preview 4 的累積更新:2016 年 5 月 10 日。
如需 .NET Framework 3.5.1 的詳細資訊,請參閱針對 TLS 系統預設版本的支援已包含在 Windows 7 SP1 和 Server 2008 R2 SP1 上的 .NET Framework 3.5.1 中 (機器翻譯)。
下列 .REG 檔案會將登錄項目及其變體設定為最安全的值:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v2.0.50727]
"SystemDefaultTlsVersions"=dword:00000001
"SchUseStrongCrypto"=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319]
"SystemDefaultTlsVersions"=dword:00000001
"SchUseStrongCrypto"=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v2.0.50727]
"SystemDefaultTlsVersions"=dword:00000001
"SchUseStrongCrypto"=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319]
"SystemDefaultTlsVersions"=dword:00000001
"SchUseStrongCrypto"=dword:00000001
在 Windows 登錄中設定安全通道通訊協定
您可以使用登錄以對您用戶端和/或伺服器應用程式交涉的通訊協定進行細微的控制。 您應用程式的網路功能會透過 Schannel (也就是安全通道的別稱) 進行。 透過設定 Schannel
,您便可以設定應用程式的行為。
請從 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols
登錄機碼開始。 在該機碼底下,您可以在 TLS 1.2
、TLS 1.3
集合中建立任何子機碼。 在那些子機碼底下,您可以建立子機碼 Client
和/或 Server
。 在 Client
和 Server
底下,您可以建立 DWORD 值 DisabledByDefault
(0 或 1) 和 Enabled
(0 或 1)。
如需詳細資訊,請參閱:TLS 登錄設定 - Schannel
The SCH_USE_STRONG_CRYPTO 旗標
啟用時 (預設會由 AppContext
參數或 Windows 登錄啟用啟用),.NET Framework 會在您的應用程式起始與伺服器的 TLS 連線時使用 SCH_USE_STRONG_CRYPTO
旗標。 .NET Framework 會將旗標傳遞至 Schannel
,以指示它停用已知的弱式密碼編譯演算法、加密套件,以及 TLS/SSL 通訊協定版本;若不這樣做,系統可能會為了取得更佳的互通性而啟用這些項目。 如需詳細資訊,請參閱
- 安全通道 \(英文\)
- SCHANNEL_CRED 結構 \(英文\)
當您明確使用 Tls11
或者 SecurityProtocolType 或 SslProtocols 的 Tls12
列舉值時,也會將 SCH_USE_STRONG_CRYPTO
旗標傳遞至 Schannel
以進行用戶端 (傳出) 連線。 SCH_USE_STRONG_CRYPTO
旗標只會用於應用程式作為用戶端角色的連線。 當您的應用程式透過設定全電腦的 Schannel
登錄設定來作為伺服器的角色時,您可以停用弱式通訊協定和演算法。