SecurityProtocol mặc định trong .NET 4.5


253

Giao thức bảo mật mặc định để liên lạc với các máy chủ hỗ trợ lên đến là TLS 1.2gì? Sẽ .NETtheo mặc định, chọn giao thức bảo mật cao nhất được hỗ trợ trên phía máy chủ hay tôi cần phải thêm một cách rõ ràng dòng mã này:

System.Net.ServicePointManager.SecurityProtocol = 
SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

Có cách nào để thay đổi mặc định này, bên cạnh thay đổi mã không?

Cuối cùng, .NET 4.0chỉ hỗ trợ tối đa TLS 1.0? tức là tôi phải nâng cấp các dự án máy khách lên 4,5 để hỗ trợ TLS 1.2.

Động lực của tôi là loại bỏ hỗ trợ cho SSLv3phía máy khách ngay cả khi máy chủ hỗ trợ nó (tôi đã có tập lệnh powershell để vô hiệu hóa điều này trong sổ đăng ký máy) và hỗ trợ giao thức TLS cao nhất mà máy chủ hỗ trợ.

Cập nhật: Nhìn vào ServicePointManagerlớp trong .NET 4.0tôi thấy không có giá trị liệt kê cho TLS 1.01.1. Trong cả hai .NET 4.0/4.5, mặc định là SecurityProtocolType.Tls|SecurityProtocolType.Ssl3. Hy vọng mặc định này sẽ không phá vỡ bằng cách vô hiệu hóa SSLv3trong sổ đăng ký.

Tuy nhiên, tôi đã quyết định tôi phải nâng cấp tất cả các ứng dụng .NET 4.5và thêm rõ ràng SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;vào tất cả các mã bootstrapping của tất cả các ứng dụng.

Điều này sẽ thực hiện các yêu cầu gửi đến các apis và dịch vụ khác nhau để không hạ cấp xuống SSLv3và nên chọn mức cao nhất TLS.

Liệu cách tiếp cận này nghe có vẻ hợp lý hoặc quá mức? Tôi có nhiều ứng dụng để cập nhật và tôi muốn chứng minh chúng trong tương lai vì tôi nghe thấy thậm chí TLS 1.0có thể bị từ chối trong tương lai gần bởi một số nhà cung cấp.

Là một khách hàng thực hiện các yêu cầu gửi đến API, việc vô hiệu hóa SSL3 trong sổ đăng ký thậm chí có ảnh hưởng đến .NET framework không? Tôi thấy theo mặc định, TLS 1.1 và 1.2 không được bật, chúng ta có phải kích hoạt nó qua sổ đăng ký không? RE http://support.microsoft.com/kb/245030 .

Sau một chút điều tra, tôi tin rằng các cài đặt đăng ký sẽ không ảnh hưởng gì vì chúng áp dụng cho IIS (khóa con máy chủ) và trình duyệt (khoá con máy khách).

Xin lỗi bài đăng này biến thành nhiều câu hỏi, tiếp theo là câu trả lời "có thể".


FYI: Thực tiễn tốt nhất mới nhất về TLS: docs.microsoft.com/en-us/dotnet/framework/network-programming/ Kẻ
JohnLBevan

Đối với những người muốn xem câu trả lời tốt nhất cho điều này, sắp xếp theo phiếu bầu!
hải quân

1
Câu hỏi và trả lời liên quan: stackoverflow.com/questions/41618766/ Người đọc nên lưu ý câu hỏi này đã cũ và các đề xuất mới hơn được đưa ra vào năm 2020.
Không hoàn lại tiền Không trả lại

Câu trả lời:


280

Một số ý kiến ​​để lại đã lưu ý rằng việc đặt System.Net.ServicePointManager.SecurityProtocolthành các giá trị cụ thể có nghĩa là ứng dụng của bạn sẽ không thể tận dụng các phiên bản TLS trong tương lai có thể trở thành giá trị mặc định trong các bản cập nhật trong tương lai cho .NET. Thay vì chỉ định một danh sách cố định các giao thức, thay vào đó bạn có thể bật hoặc tắt các giao thức mà bạn biết và quan tâm, để lại bất kỳ giao thức nào khác.

Để bật TLS 1.1 và 1.2 mà không ảnh hưởng đến các giao thức khác:

System.Net.ServicePointManager.SecurityProtocol |= 
    SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

Lưu ý việc sử dụng |=để bật các cờ này mà không tắt các cờ khác.

Để tắt SSL3 mà không ảnh hưởng đến các giao thức khác:

System.Net.ServicePointManager.SecurityProtocol &= ~SecurityProtocolType.Ssl3;

6
Đây thực sự là câu trả lời chính xác. Câu trả lời được chấp nhận sẽ đảm bảo rằng ứng dụng của bạn sẽ luôn tắt các phiên bản TLS mới trừ khi bạn quay lại và cập nhật mã của mình.
Connor

5
@Gertsen Không, đó là một bitwise hoặc, vì vậy nó chỉ bật các bit thích hợp nếu chúng bị tắt. Nếu các bit đó đã được bật, không có thay đổi xảy ra.
Scott

3
Và tương đương PowerShell của điều này là [Net.ServicePointManager]::SecurityProtocol = ([Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls11 -bor [Net.SecurityProtocolType]::Tls12) Invoke-RestMethod dựa trên cùng các thư viện .NET framework bên dưới.
Martin Hollingsworth

15
Vì không ai nói về việc đặt mã này ở đâu, tôi đã đặt nó thành công vào Application_Start của Global.asax.cs cho ứng dụng ASP.NET MVC của tôi. Tôi đang tìm cách làm thế nào để các yêu cầu SMTP của tôi được gửi qua TLS1.2 và KHÔNG qua TLS1.0. Tôi cũng đã thêm & = ~ SecurityProtocolType.Tls để tắt TLS 1.0
Greg Veres

2
Trong VB tương đương làNet.ServicePointManager.SecurityProtocol = Net.ServicePointManager.SecurityProtocol OR Net.SecurityProtocolType.Tls12 OR Net.SecurityProtocolType.Tls12
Codepaces 14/2/19

188

Mặc định System.Net.ServicePointManager.SecurityProtocoltrong cả .NET 4.0/4.5SecurityProtocolType.Tls|SecurityProtocolType.Ssl3.

.NET 4.0hỗ trợ lên đến TLS 1.0trong khi .NET 4.5hỗ trợ lên đếnTLS 1.2

Tuy nhiên, nhắm mục tiêu ứng dụng .NET 4.0vẫn có thể hỗ trợ tối đa TLS 1.2nếu .NET 4.5được cài đặt trong cùng một môi trường. .NET 4.5cài đặt trên đầu trang .NET 4.0, thay thế System.dll.

Tôi đã xác minh điều này bằng cách quan sát giao thức bảo mật chính xác được đặt trong lưu lượng truy cập fiddler4và bằng cách đặt thủ công các giá trị được liệt kê trong một .NET 4.0dự án:

ServicePointManager.SecurityProtocol = (SecurityProtocolType)192 |
(SecurityProtocolType)768 | (SecurityProtocolType)3072;

Tài liệu tham khảo:

namespace System.Net
{
    [System.Flags]
    public enum SecurityProtocolType
    {
       Ssl3 = 48,
       Tls = 192,
       Tls11 = 768,
       Tls12 = 3072,
    }
}

Nếu bạn cố gắng hack trên một môi trường .NET 4.0được cài đặt CHỈ , bạn sẽ nhận được ngoại lệ:

Ngoại lệ chưa được xử lý: System.NotSupportedException: Giao thức bảo mật được yêu cầu không được hỗ trợ. tại System.Net.ServicePointManager.set_SecurityProtocol (SecurityProtocolType v alue)

Tuy nhiên, tôi sẽ không đề xuất "hack" này vì bản vá trong tương lai, v.v. có thể phá vỡ nó. *

Do đó, tôi đã quyết định cách tốt nhất để xóa hỗ trợ SSLv3là:

  1. Nâng cấp tất cả các ứng dụng lên .NET 4.5
  2. Thêm phần sau vào mã tăng cường để ghi đè mặc định và bằng chứng trong tương lai:

    System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

* Ai đó sửa tôi nếu hack này sai, nhưng các thử nghiệm ban đầu tôi thấy nó hoạt động


6
Vui lòng xem Imperialialviolet.org/2014/12/08/poodleagain.html "Đây có vẻ là một thời điểm tốt để nhắc lại rằng mọi thứ ít hơn TLS 1.2 với bộ mật mã AEAD bị phá vỡ bằng mật mã."
Neil

3
@Mathew, bằng cách xem mã nguồn của ServicePointManager.csthấy referencesource.microsoft.com/#System/net/System/Net/...
Luke Hutton

12
Tôi liên tục thấy mọi người tuyên bố .NET 4.5mặc định cho Tls12 - nhưng như bạn đã đặt ở đây, thì không. Nó cung cấp cho bạn tùy chọn để sử dụng nó choSecurityProtocol
Don Cheadle

17
Tôi sẽ không đưa ra câu trả lời này vì nó cung cấp nhiều thông tin hữu ích, nhưng thực hiện phiên bản giao thức được mã hóa cứng không phải là ý tưởng hay vì nó sẽ hạn chế ứng dụng sử dụng mã hóa tốt nhất hiện có và có thể dẫn đến các vấn đề bảo mật. Việc đăng ký thay đổi để thay đổi hành vi mặc định của .Net để thực sự hỗ trợ các giao thức hiện đại là rất thích hợp. (Tuy nhiên, đáng chú ý là thay đổi sổ đăng ký cũng vô hiệu hóa SSL v3.)
AJ Henderson

6
Trên FW 4.6 và 4.7, mặc định bây giờ SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12là theo support.microsoft.com/en-us/help/3069494/ Kẻ
Ian Kemp

68

Bạn có thể ghi đè hành vi mặc định trong sổ đăng ký sau:

Key  : HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319 
Value: SchUseStrongCrypto
Type: REG_DWORD
Data : 1

Key  : HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319
Value: SchUseStrongCrypto
Type: REG_DWORD
Data : 1

Để biết chi tiết, xin vui lòng xem việc thực hiệnServicePointManager .


Cảm ơn, tôi không biết về điều này. Tôi sẽ kiểm tra nó. Tôi đã tạo một tập lệnh powersrc
Luke Hutton

6
Thay đổi registry không giống như một giải pháp tốt. Nếu ứng dụng muốn hỗ trợ TLS1 thì ứng dụng nên lấy cate về nó. Không phải môi trường chạy. Nếu không, nó có thể gây hại cho các ứng dụng khác hoặc khiến cho việc triển khai và nâng cấp ứng dụng của bạn trở nên tồi tệ.
Mikhail G

13
@MikhailG hoàn toàn ngược lại. Thay đổi đăng ký là phương pháp thích hợp hơn. SChannel cung cấp một bản tóm tắt của cuộc đàm phán cơ bản và bạn muốn ứng dụng của mình sử dụng bất cứ mức độ bảo mật được hỗ trợ cao nhất nào. Hạn chế một cách giả tạo trong phần mềm dẫn đến các vấn đề trong tương lai khi các giao thức mới được phát hành và phần mềm của bạn không thể sử dụng chúng. Sẽ thật tuyệt nếu có một tùy chọn để nói chỉ sử dụng tốt hơn một giao thức nhất định trong phần mềm, nhưng không có tùy chọn nào cho điều đó mà không ngăn các phiên bản trong tương lai hoạt động. Mặc dù vậy, việc vô hiệu hóa SSL v3 với thay đổi đó ..
AJ Henderson

13
Dòng lệnh: reg add HKLM\SOFTWARE\Microsoft\.NETFramework\v4.0.30319 /v SchUseStrongCrypto /t REG_DWORD /d 1 /reg:64(và / hoặc /reg:32)
Kevin Smyth

7
@MikhailG: Đặt registry không ngăn các ứng dụng hỗ trợ các giao thức cũ hơn. Nó chỉ thay đổi mặc định (bao gồm cả tls 1.0 như bây giờ). Hơn nữa, hành vi mặc định trong .Net 4.6+ là sử dụng tiền điện tử mạnh; trong trường hợp đó, mục đăng ký này sẽ chỉ hữu ích như một phương tiện để vô hiệu hóa tiền điện tử mạnh.
Brian

51

Tạo một tệp văn bản có .regphần mở rộng và các nội dung sau:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319]
"SchUseStrongCrypto"=dword:00000001

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319]
"SchUseStrongCrypto"=dword:00000001

Hoặc tải xuống từ nguồn sau:

https://tls1test.salesforce.com/s/NET40-Enable-TLS-1_2.reg

Nhấp đúp để cài đặt ...


3
Liên kết bạn cung cấp dường như có vấn đề về chứng chỉ SSL.
NathanAldenSr

Ngay cả khi tôi thêm các khóa registry này, tôi vẫn gặp vấn đề đó. Bất kỳ ý tưởng ?
Samidjo

@Samidjo - Bạn đang sử dụng phiên bản .NET nào? Câu trả lời của Luke đi sâu vào chi tiết hơn tôi rất nhiều, nhưng có vẻ như bạn ít nhất phải cài đặt .NET 4.5. Ngoài ra, nếu bạn vừa thực hiện thay đổi, bạn có thể phải tái chế nhóm ứng dụng. Đây là những loại dự đoán, vì vậy nếu không có thêm chi tiết, tôi có thể giúp nhiều hơn nữa :)
dana

2
Một bản vá được áp dụng gần đây support.microsoft.com/en-us/help/4019114/ trên máy chủ khiến ứng dụng .net 4.5.2 của chúng tôi không thành công trên các yêu cầu https REST. Những chìa khóa đã giải quyết vấn đề của chúng tôi.
Kleinux

21

Tôi đã thấy rằng khi tôi chỉ định TLS 1.2 thì nó vẫn sẽ thương lượng xuống 1.1. System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

Tôi đã chỉ định điều này trong phương thức khởi động Global.asax cho ứng dụng web .net 4.5 của tôi.


2
Giao thức bảo mật được hỗ trợ trên máy chủ là gì? Tôi tin rằng đó cũng là yếu tố ở đây và có thể 1.1 là mới nhất trên máy chủ. www.passionatecoder.ca
Ehsan

14
Được nâng cấp bởi vì đây là câu trả lời duy nhất nêu rõ WHERE đặt dòng mã là giải pháp.
jgerman

1
Máy khách (ví dụ: C # WebClient của bạn) và Máy chủ (máy chủ API bạn đang gọi) sẽ đàm phán để sử dụng giao thức cao nhất mà cả hai hỗ trợ. Vì vậy, nếu khách hàng của bạn hỗ trợ TLS 1.2, nhưng máy chủ chỉ có TLS 1.1 - Khách hàng sẽ sử dụng TLS 1.1 (trừ khi bạn XÓA TLS 1.1 từ khách hàng của mình - trong trường hợp họ không thể tìm thấy giao thức được hỗ trợ lẫn nhau và Khách hàng sẽ gặp lỗi)
Don Cheadle

Phải thêm bằng System.Net trong global.asax.cs
Patrick

16

Mã sau sẽ:

  • in giao thức kích hoạt
  • in các giao thức có sẵn
  • bật TLS1.2 nếu nền tảng hỗ trợ và nếu nó không được kích hoạt để bắt đầu
  • vô hiệu hóa SSL3 nếu nó được kích hoạt
  • in kết quả cuối cùng

Hằng số:

  • 48 là SSL3
  • 192 là TLS1
  • 768 là TLS1.1
  • 3072 là TLS1.2

Các giao thức khác sẽ không bị ảnh hưởng. Điều này làm cho điều này tương thích với các giao thức trong tương lai (Tls1.3, v.v.).

// print initial status
    Console.WriteLine("Runtime: " + System.Diagnostics.FileVersionInfo.GetVersionInfo(typeof(int).Assembly.Location).ProductVersion);
    Console.WriteLine("Enabled protocols:   " + ServicePointManager.SecurityProtocol);
    Console.WriteLine("Available protocols: ");
    Boolean platformSupportsTls12 = false;
    foreach (SecurityProtocolType protocol in Enum.GetValues(typeof(SecurityProtocolType))) {                
        Console.WriteLine(protocol.GetHashCode());
        if (protocol.GetHashCode() == 3072){
            platformSupportsTls12 = true;
        }
    }
    Console.WriteLine("Is Tls12 enabled: " + ServicePointManager.SecurityProtocol.HasFlag((SecurityProtocolType)3072));    


// enable Tls12, if possible
    if (!ServicePointManager.SecurityProtocol.HasFlag((SecurityProtocolType)3072)){
        if (platformSupportsTls12){
            Console.WriteLine("Platform supports Tls12, but it is not enabled. Enabling it now.");
            ServicePointManager.SecurityProtocol |= (SecurityProtocolType)3072;
        } else {
            Console.WriteLine("Platform does not supports Tls12.");
        }
    }

// disable ssl3
   if (ServicePointManager.SecurityProtocol.HasFlag(SecurityProtocolType.Ssl3)) { 
      Console.WriteLine("Ssl3SSL3 is enabled. Disabling it now.");
      // disable SSL3. Has no negative impact if SSL3 is already disabled. The enclosing "if" if just for illustration.
      System.Net.ServicePointManager.SecurityProtocol &= ~SecurityProtocolType.Ssl3;                      
   }
    Console.WriteLine("Enabled protocols:   " + ServicePointManager.SecurityProtocol);

Đầu ra

Runtime: 4.7.2114.0
Enabled protocols:   Ssl3, Tls
Available protocols: 
0
48
192
768
3072
Is Tls12 enabled: False
Platform supports Tls12, but it is not enabled. Enabling it now.
Ssl3 is enabled. Disabling it now.
Enabled protocols:   Tls, Tls12

14

Tôi gặp vấn đề khi khách hàng của tôi nâng cấp TLS từ 1.0 lên 1.2. Ứng dụng của tôi đang sử dụng .net framework 3.5 và chạy trên máy chủ. Vì vậy, tôi đã sửa nó bằng cách này:

  1. Sửa chương trình

Trước khi gọi HttpWebRequest.GetResponse () hãy thêm lệnh này:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolTypeExtensions.Tls11 | SecurityProtocolTypeExtensions.Tls12;

Phần mở rộng 2 DLL bằng cách thêm 2 lớp mới: System.Net và System.Security.Authentication

    namespace System.Net
    {
        using System.Security.Authentication;
        public static class SecurityProtocolTypeExtensions
        {
            public const SecurityProtocolType Tls12 = (SecurityProtocolType)SslProtocolsExtensions.Tls12;
            public const SecurityProtocolType Tls11 = (SecurityProtocolType)SslProtocolsExtensions.Tls11;
            public const SecurityProtocolType SystemDefault = (SecurityProtocolType)0;
        }
    } 

    namespace System.Security.Authentication
    {
        public static class SslProtocolsExtensions
        {
            public const SslProtocols Tls12 = (SslProtocols)0x00000C00;
            public const SslProtocols Tls11 = (SslProtocols)0x00000300;
        }
    } 
  1. Cập nhật lô Microsoft

Tải xuống hàng loạt:

  • Đối với windows 2008 R2: windows6.1-kb3154518-x64.msu
  • Đối với windows 2012 R2: windows8.1-kb3154520-x64.msu

Để tải về hàng loạt và biết thêm chi tiết bạn có thể xem tại đây:

https://support.microsoft.com/en-us/help/3154518/support-for-tls-system-default-versions-included-in-the-.net-framework-3.5.1-on-windows-7 -sp1-và-server-2008-r2-sp1


1
Có thể thay đổi SecurityProtocol mà không thay đổi mã nguồn? như máy.config hoặc app.config.
ahankendi

1
Ồ Đó là voodoo của giải thưởng năm..thứ ... ngay tại đó. Bạn đá vùng ngoại ô!
granadaCoder

14

Cơ chế thay đổi đăng ký làm việc cho tôi sau một cuộc đấu tranh. Trên thực tế, ứng dụng của tôi đã chạy được 32 bit. Vì vậy, tôi đã phải thay đổi giá trị theo đường dẫn.

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft.NETFramework\v4.0.30319

Loại giá trị cần phải là DWORD và giá trị trên 0. Sử dụng tốt hơn 1.Cài đặt đăng ký để tải ứng dụng .Net 4.0 sử dụng TLS 1.2 được cung cấp .Net 4.5 được cài đặt trong máy.


Nó không chính xác. Đối với .NET 4.5.2, điều này cần được đặt thành 1 (hoặc cao hơn); nhưng đối với .NET 4.6, nó không được đặt thành 0 (nghĩa là có thể không được đặt).
Jirka Hanika

Oh tôi đã không kiểm tra trong .Net 4.6. Phát hiện của tôi có trong blogpost joymonscode.blogspot.com/2015/08/ từ
Joy George Kunjikkuru

Khóa sổ đăng ký bạn đề cập nên đọc "Wow6432Node". Bạn đã bỏ qua phần "Nút" vì một số lý do. Tôi đã cố gắng chỉnh sửa phản hồi của bạn nhưng thay đổi của tôi chỉ có 4 chữ cái nên nó sẽ không cho phép tôi. : \
Jeffrey LeCours

Tôi đã phải trả lại IIS để mặc định cài đặt này hoạt động như mặc định.
Jeff Mitchell

10

Tôi đang chạy theo .NET 4.5.2 và tôi không hài lòng với bất kỳ câu trả lời nào trong số này. Khi tôi đang nói chuyện với một hệ thống hỗ trợ TLS 1.2 và xem SSL3, TLS 1.0 và TLS 1.1 đều bị hỏng và không an toàn khi sử dụng, tôi không muốn kích hoạt các giao thức này. Trong .NET 4.5.2, các giao thức SSL3 và TLS 1.0 đều được bật theo mặc định, mà tôi có thể thấy trong mã bằng cách kiểm tra ServicePointManager.SecurityProtocol. Trong .NET 4.7, có cái mớiSystemDefaultchế độ giao thức bàn giao rõ ràng việc lựa chọn giao thức cho HĐH, nơi tôi tin rằng việc dựa vào đăng ký hoặc các cài đặt cấu hình hệ thống khác sẽ phù hợp. Tuy nhiên, điều đó dường như không được hỗ trợ trong .NET 4.5.2. Vì lợi ích của việc viết mã tương thích chuyển tiếp, điều đó sẽ tiếp tục đưa ra quyết định đúng đắn ngay cả khi TLS 1.2 chắc chắn bị phá vỡ trong tương lai hoặc khi tôi nâng cấp lên .NET 4.7+ và giao thêm trách nhiệm cho việc chọn giao thức phù hợp cho HĐH , Tôi đã thông qua mã sau đây:

SecurityProtocolType securityProtocols = ServicePointManager.SecurityProtocol;
if (securityProtocols.HasFlag(SecurityProtocolType.Ssl3) || securityProtocols.HasFlag(SecurityProtocolType.Tls) || securityProtocols.HasFlag(SecurityProtocolType.Tls11))
{
    securityProtocols &= ~(SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11);
    if (securityProtocols == 0)
    {
        securityProtocols |= SecurityProtocolType.Tls12;
    }
    ServicePointManager.SecurityProtocol = securityProtocols;
}

Mã này sẽ phát hiện khi một giao thức không an toàn đã biết được bật và trong trường hợp này, chúng tôi sẽ xóa các giao thức không an toàn này. Nếu không còn giao thức rõ ràng nào khác, thì chúng tôi sẽ buộc kích hoạt TLS 1.2, vì giao thức bảo mật duy nhất được biết đến được .NET hỗ trợ tại thời điểm này. Mã này tương thích về phía trước, vì nó sẽ xem xét các loại giao thức mới mà nó không biết về việc được thêm vào trong tương lai và nó cũng sẽ chơi tốt với giao thức mớiSystemDefaulttrạng thái trong .NET 4.7, nghĩa là tôi sẽ không phải truy cập lại mã này trong tương lai. Tôi thực sự khuyên bạn nên áp dụng một cách tiếp cận như thế này, thay vì mã hóa cứng bất kỳ trạng thái giao thức bảo mật cụ thể nào một cách vô điều kiện, nếu không, bạn sẽ phải biên dịch lại và thay thế máy khách của mình bằng một phiên bản mới để nâng cấp lên giao thức bảo mật mới khi TLS 1.2 chắc chắn bị phá vỡ, hoặc nhiều khả năng bạn sẽ phải để các giao thức không an toàn hiện có được bật trong nhiều năm trên máy chủ của bạn, khiến tổ chức của bạn trở thành mục tiêu cho các cuộc tấn công.


1
Câu trả lời này có vẻ như được suy nghĩ nhiều nhất, tuy nhiên, trừ khi tôi thiếu một cái gì đó, tôi không chắc nó sẽ tương thích về phía trước mỗi khi TLS 1.2 chắc chắn bị phá vỡ. Từ những gì tôi thấy trong ứng dụng .NET 4.7.2 của mình, SecurityProtocolType.SystemDefaultcờ đánh giá 0, do đó, việc kiểm tra if (securityProtocols == 0)với cờ bao gồm bitwise hoặc cờ cho TLS 1.2 sẽ luôn bao gồm TLS 1.2, ngay cả sau khi nó bị "vỡ", phải không? Không chụp sắc nét ở đây. Tôi thực sự đang cố gắng tìm ra con đường tốt nhất phía trước.
Griswald_911

Tôi đã sửa đổi mã của bạn để bao gồm mã này và nó có vẻ hoạt động và tương thích về phía trước : if (!Enum.IsDefined(typeof(SecurityProtocolType), 0) && securityProtocols == 0) { securityProtocols |= SecurityProtocolType.Tls12; }.
Griswald_911

@ Griswald_911, tôi có mã tương tự trong ứng dụng bảng điều khiển 4.7.2 của mình và tôi thấy dòng này securityProtocols |= SecurityProtocolType.Tls12;(không có khối chặn) không duy trì SystemDefault, sau đó, securityProt Protocol chỉ có TLS2. Vậy ý bạn là khi giá trị là SystemDefault, không nên cập nhật giá trị nào? Về khả năng tương thích về phía trước, bạn có cho rằng HĐH sẽ đảm nhiệm việc kích hoạt giao thức mới hơn như TLS 1.3 không?
Dương

@Yang - Đúng. Dòng securityProtocols |= SecurityProtocolType.Tls12;' will add TLS 1.2, but because the SecurityProtocolType` enum có một [Flags]thuộc tính và giá trị liệt kê SystemDefault là 0, giá trị SystemDefault sẽ bị tước, ngay cả khi nó đã được đặt trước đó. Kết quả cuối cùng là bạn có thể đặt thành SevicePointManager.SecurityProtocol 0 hoặc thành bất kỳ kết hợp nào của các giá trị liệt kê khác. Nếu bạn đặt nó thành SystemDefault, về cơ bản bạn sẽ từ chối chỉ định giao thức và để HĐH quyết định.
Griswald_911

1
@Yang - Vấn đề là, sau khi đặt giá trị thành SystemDefault, ứng dụng của bạn sẽ sử dụng bất cứ thứ gì mà HĐH chỉ định - đó là TLS 1.2 trong các phiên bản mới nhất của Windows 10. Ý tưởng là, trong tương lai khi TLS 1.3 trở thành tiêu chuẩn, bạn không cần phải sửa đổi ứng dụng của mình để kế thừa chức năng đó. Xem tài liệu ở đây , nơi SystemDefault "cho phép hệ điều hành chọn giao thức tốt nhất để sử dụng và chặn các giao thức không an toàn".
Griswald_911

6

Microsoft gần đây đã công bố các thực tiễn tốt nhất xung quanh điều này. https://docs.microsoft.com/en-us/dotnet/framework/network-programming/tls

Tóm lược

Target .Net Framework 4.7, xóa mọi mã cài đặt SecurityProtocol, do đó HĐH sẽ đảm bảo bạn sử dụng giải pháp an toàn nhất.

Lưu ý: Bạn cũng cần đảm bảo rằng phiên bản TLS mới nhất được hỗ trợ & kích hoạt trên HĐH của bạn.

OS                          TLS 1.2 support

Windows 10                  \_ Supported, and enabled by default.
Windows Server 2016         /   
Windows 8.1                 \_ Supported, and enabled by default.
Windows Server 2012 R2      /
Windows 8.0                 \_ Supported, and enabled by default.
Windows Server 2012         /
Windows 7 SP1               \_ Supported, but not enabled by default*.
Windows Server 2008 R2 SP1  /
Windows Server 2008         -  Support for TLS 1.2 and TLS 1.1 requires an update. See Update to add support for TLS 1.1 and TLS 1.2 in Windows Server 2008 SP2.
Windows Vista               -  Not supported.

* To enable TLS1.2 via the registry see https://docs.microsoft.com/en-us/windows-server/security/tls/tls-registry-settings#tls-12 

    Path: HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS1.2\Server

        Property: Enabled
        Type: REG_DWORD
        Value: 1

        Property: DisabledByDefault 
        Type: REG_DWORD
        Value: 0

    Path: HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS1.2\Client

        Property: Enabled
        Type: REG_DWORD
        Value: 1

        Property: DisabledByDefault 
        Type: REG_DWORD
        Value: 0

Để biết thêm thông tin và các khung cũ hơn, vui lòng tham khảo liên kết MS.


3
Vấn đề là tls 1.1 và tls 1.2 sẽ không hoạt động trên Windows 7 và Server 2008 nếu bạn làm theo hướng dẫn (giữ SecurityProtocolType.SystemDefault) vì chúng không được "bật" (bất cứ điều gì có nghĩa) trong các os này mà không thay đổi đăng ký. Điều này làm cho SystemDefault trong thực tế bị phá vỡ bởi thiết kế. Microsoft thực sự đã làm hỏng điều này.
osexpert

Đẹp một, cảm ơn @osexpert, bắt tốt. Tôi đã sửa đổi câu trả lời để bao gồm thông tin về các HĐH được hỗ trợ, do đó, không có gì ngạc nhiên đối với những người chạy các HĐH cũ hơn khi chỉ nhắm mục tiêu 4.7 là không đủ.
JohnLBevan

1
NB: Ngoài ra còn có một KB để cho phép các giao thức mới hơn trên một số hệ điều hành: support.microsoft.com/en-my/help/3140245/...
JohnLBevan

1
Nếu cài đặt đăng ký không phải là một tùy chọn, tôi nghĩ đây là giải pháp tốt nhất cho .NET 4.7+: if (System.Environment.OSVersion.Version < new Version(6, 2) /* Windows 8 */) ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; else ServicePointManager.SecurityProtocol = SecurityProtocolType.SystemDefault;
osexpert

5

Để hoàn thiện, đây là tập lệnh Powershell đặt các khóa đăng ký đã nói ở trên:

new-itemproperty -path "HKLM:\SOFTWARE\Microsoft\.NETFramework\v4.0.30319" -name "SchUseStrongCrypto" -Value 1 -PropertyType "DWord";
new-itemproperty -path "HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319" -name "SchUseStrongCrypto" -Value 1 -PropertyType "DWord"

2

Một cách khác để mã hóa cứng ServicePointManager.SecurityProtocolhoặc khóa SchUseStrongCrypto rõ ràng như đã đề cập ở trên:
Bạn có thể yêu cầu .NET sử dụng các cài đặt SCHANNEL mặc định với khóa SystemDefaultTlsVersions,
ví dụ:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319] "SystemDefaultTlsVersions"=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319] "SystemDefaultTlsVersions"=dword:00000001

2

Giải pháp TỐT NHẤT cho vấn đề này dường như là nâng cấp lên ít nhất .NET 4.6 trở lên, nó sẽ tự động chọn các giao thức mạnh cũng như mật mã mạnh.

Nếu bạn không thể nâng cấp lên .NET 4.6, lời khuyên về cài đặt

System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11 | SecurityProtatioType.Tls12;

Và sử dụng các cài đặt đăng ký:

HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft.NETFramework \ v4.0.30319 - SchUseStrongCrypto = DWORD của 1 HKEY_LOCAL_MACHINE \ SOFTWARE \ Wow6432Node \ Microsoft.NETFramework \ v4.0.30319 - SchUseStrongCrypto = DWORD

Kết quả trong việc sử dụng một cái gì đó khác với TLS 1.0 và một mật mã mạnh.

Trong thử nghiệm của tôi, chỉ có cài đặt trong Wow6432Node tạo ra sự khác biệt, mặc dù ứng dụng thử nghiệm của tôi được xây dựng cho Bất kỳ CPU nào.


Làm rõ: bạn chỉ cần đặt SevicePointManager.SecurityProtocol HOẶC đặt cài đặt đăng ký. Không cần phải làm cả hai. Đối với ứng dụng của mình, tôi đã chọn chỉ đặt ServicePointManager.SecurityProtocol. Lý do của tôi là việc cài đặt sổ đăng ký ảnh hưởng đến toàn bộ máy và tôi không muốn ứng dụng của người khác bị phá vỡ vì nó phụ thuộc vào TLS 1.0.
GWC

1

Theo các thực tiễn tốt nhất về Bảo mật lớp vận chuyển (TLS) với .NET Framework : Để đảm bảo các ứng dụng .NET Framework vẫn an toàn, phiên bản TLS không nên được mã hóa cứng. Thay vào đó, đặt các khóa đăng ký: SystemDefaultTlsVersions SchUseStrongCrypto :

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

0

Nếu bạn có thể sử dụng .NET 4.7.1 hoặc mới hơn, nó sẽ sử dụng TLS 1.2 làm giao thức tối thiểu dựa trên khả năng của hệ điều hành. Theo khuyến nghị của Microsoft:

To ensure .NET Framework applications remain secure, the TLS version should not be hardcoded. .NET Framework applications should use the TLS version the operating system (OS) supports.

-2

Đối với Khóa: HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft.NETFramework \ v4.0.30319 Giá trị: SchUseStrongCrypto

Bạn phải đặt giá trị thành 1.


5
Tôi nghĩ rằng bạn đang bị hạ thấp bởi vì câu trả lời tương tự @Jira Mares đưa ra, nhưng với ít chi tiết hơn
Stuart Siegler
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.