SecurityProtocol เริ่มต้นใน. NET 4.5


253

โพรโทคอลความปลอดภัยเริ่มต้นสำหรับการสื่อสารกับเซิร์ฟเวอร์ที่รองรับสูงสุดTLS 1.2คืออะไร จะ.NETเป็นค่าเริ่มต้นให้เลือกโปรโตคอลความปลอดภัยสูงสุดได้รับการสนับสนุนในด้านเซิร์ฟเวอร์หรือฉันจะต้องชัดเจนเพิ่มบรรทัดของรหัสนี้:

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

มีวิธีในการเปลี่ยนค่าเริ่มต้นนี้นอกจากการเปลี่ยนรหัสหรือไม่

สุดท้ายนี้.NET 4.0สนับสนุนได้มากถึงเท่านั้นTLS 1.0? คือผมต้องปรับโครงการของลูกค้า 4.5 TLS 1.2ที่ให้การสนับสนุน

แรงจูงใจของฉันคือการลบการสนับสนุนSSLv3ในฝั่งไคลเอ็นต์แม้ว่าเซิร์ฟเวอร์รองรับ (ฉันมีสคริปต์ PowerShell เพื่อปิดการใช้งานนี้ในรีจิสทรีของเครื่อง) และเพื่อรองรับโปรโตคอล TLS สูงสุดที่เซิร์ฟเวอร์รองรับ

ปรับปรุง: กำลังมองหาที่ServicePointManagerเรียนใน.NET 4.0ผมเห็นไม่มีค่าแจกแจงสำหรับและTLS 1.0 1.1ในทั้งสองเริ่มต้นคือ.NET 4.0/4.5 SecurityProtocolType.Tls|SecurityProtocolType.Ssl3หวังว่าค่าเริ่มต้นนี้จะไม่แตกเมื่อปิดใช้งานSSLv3ในรีจิสทรี

อย่างไรก็ตามฉันตัดสินใจว่าฉันจะต้องอัปเกรดแอพทั้งหมดเป็น.NET 4.5และเพิ่มอย่างชัดเจนSecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;ในรหัส bootstrapping ของแอปพลิเคชันทั้งหมด

ซึ่งจะทำให้ขาออกการร้องขอไปยัง APIs และบริการต่างๆที่จะไม่ปรับลดและควรเลือกระดับสูงสุดของSSLv3TLS

วิธีการนี้ฟังดูสมเหตุสมผลหรือเกินความจริงหรือไม่? ฉันมีแอปพลิเคชั่นมากมายที่ต้องอัปเดตและฉันต้องการพิสูจน์ในอนาคตเนื่องจากฉันได้ยินว่าTLS 1.0อาจเลิกใช้งานในอนาคตอันใกล้โดยผู้ให้บริการบางราย

ในฐานะที่เป็นลูกค้าที่ทำการร้องขอขาออกไปยัง APIs การปิดใช้งาน SSL3 ในรีจิสทรีจะมีผลใน. NET Framework หรือไม่ ฉันดูตามค่าเริ่มต้น TLS 1.1 และ 1.2 ไม่ได้เปิดใช้งานเราต้องเปิดใช้งานผ่านรีจิสทรีหรือไม่ RE http://support.microsoft.com/kb/245030

หลังจากการตรวจสอบเล็กน้อยฉันเชื่อว่าการตั้งค่ารีจิสทรีจะไม่มีผลกระทบเนื่องจากจะใช้กับ IIS (คีย์ย่อยของเซิร์ฟเวอร์) และเบราว์เซอร์ (คีย์ย่อยของไคลเอ็นต์)

ขออภัยโพสต์นี้กลายเป็นคำถามหลายข้อติดตามด้วยคำตอบ "อาจจะ"


FYI: แนวปฏิบัติที่ดีที่สุดล่าสุดเกี่ยวกับ TLS: docs.microsoft.com/en-us/dotnet/framework/network-programming/?hl=th
JohnLBevan

สำหรับผู้ที่ต้องการเห็นคำตอบที่ดีที่สุดให้เรียงตามคะแนนโหวต!
navule

1
SO Q&A ที่เกี่ยวข้อง: stackoverflow.com/questions/41618766/… ผู้อ่านควรทราบว่าคำถามนี้มีอายุมากขึ้นและมีคำแนะนำที่ใหม่กว่าในปี 2020
ไม่มีการคืนเงินไม่มีผลตอบแทน

คำตอบ:


280

ความคิดเห็นที่ออกจากการตั้งค่าSystem.Net.ServicePointManager.SecurityProtocolบางอย่างระบุว่าการตั้งค่าเป็นค่าเฉพาะหมายความว่าแอปของคุณจะไม่สามารถใช้ประโยชน์จากเวอร์ชัน TLS ในอนาคตที่อาจกลายเป็นค่าเริ่มต้นในการอัปเดตเป็น. NET ในอนาคต แทนที่จะระบุรายการโปรโตคอลที่แน่นอนคุณสามารถเปิดหรือปิดโปรโตคอลที่คุณรู้จักและใส่ใจแทนได้

หากต้องการเปิด TLS 1.1 และ 1.2 โดยไม่มีผลกับโปรโตคอลอื่น:

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

สังเกตการใช้|=เพื่อเปิดแฟล็กเหล่านี้โดยไม่ปิดแฟล็กอื่น

หากต้องการปิด SSL3 โดยไม่กระทบต่อโปรโตคอลอื่น:

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

6
นี่คือคำตอบที่ถูกต้องจริงๆ คำตอบที่ได้รับการยอมรับจะช่วยให้มั่นใจว่าแอปของคุณจะสลับรุ่น TLS ใหม่ทุกครั้งเว้นแต่คุณจะกลับไปและอัปเดตรหัสของคุณ
คอนเนอร์

5
@Gertsen ไม่มันเป็นค่าบิตหรือดังนั้นจะเปิดบิตที่เหมาะสมหากปิด หากบิตเหล่านั้นเปิดอยู่จะไม่มีการเปลี่ยนแปลงเกิดขึ้น
สกอตต์

3
และ PowerShell ที่เทียบเท่ากับสิ่งนี้คือ[Net.ServicePointManager]::SecurityProtocol = ([Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls11 -bor [Net.SecurityProtocolType]::Tls12) Invoke-RestMethod อาศัยไลบรารีกรอบงาน. NET ที่เหมือนกัน
Martin Hollingsworth

15
เนื่องจากไม่มีใครพูดถึงตำแหน่งที่จะวางรหัสนี้ฉันจึงใส่ลงใน Application_Start of Global.asax.cs สำหรับแอปพลิเคชัน ASP.NET MVC ของฉัน ฉันกำลังมองหาวิธีรับคำขอ SMTP ของฉันที่จะส่งผ่าน TLS1.2 และไม่เกิน TLS1.0 ฉันยังเพิ่ม & = ~ SecurityProtocolType.Tls เพื่อปิด TLS 1.0
Greg Veres

2
ใน VB เทียบเท่าคือNet.ServicePointManager.SecurityProtocol = Net.ServicePointManager.SecurityProtocol OR Net.SecurityProtocolType.Tls12 OR Net.SecurityProtocolType.Tls12
Codespaced

188

เริ่มต้นSystem.Net.ServicePointManager.SecurityProtocolทั้งใน .NET คือ4.0/4.5SecurityProtocolType.Tls|SecurityProtocolType.Ssl3

.NET 4.0รองรับได้ถึงTLS 1.0ในขณะที่.NET 4.5รองรับได้ถึงTLS 1.2

อย่างไรก็ตามการกำหนดเป้าหมายของแอปพลิเคชัน.NET 4.0ยังคงสามารถรองรับได้TLS 1.2หาก.NET 4.5ติดตั้งในสภาพแวดล้อมเดียวกัน .NET 4.5ติดตั้งอยู่ด้านบนของแทน.NET 4.0System.dll

ฉันได้ตรวจสอบแล้วโดยการสังเกตโปรโตคอลความปลอดภัยที่ถูกต้องที่ตั้งไว้ในทราฟฟิกด้วยfiddler4และโดยการตั้งค่าด้วยตนเองใน.NET 4.0โครงการ

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

อ้างอิง:

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

หากคุณพยายามแฮ็คในสภาพแวดล้อมที่.NET 4.0ติดตั้งเพียงอย่างเดียวคุณจะได้รับข้อยกเว้น:

ข้อยกเว้น Unhandled: System.NotSupportedException: ไม่สนับสนุนโปรโตคอลความปลอดภัยที่ร้องขอ ที่ System.Net.ServicePointManager.set_SecurityProtocol (SecurityProtocolType v alue)

อย่างไรก็ตามฉันจะไม่แนะนำ "แฮ็ค" นี้เนื่องจากแพทช์ในอนาคต ฯลฯ อาจแตกได้ *

ดังนั้นฉันได้ตัดสินใจเส้นทางที่ดีที่สุดในการลบการสนับสนุนSSLv3คือ

  1. อัปเกรดแอปพลิเคชันทั้งหมดเป็น .NET 4.5
  2. เพิ่มต่อไปนี้เพื่อเพิ่มรหัสเพื่อแทนที่ค่าเริ่มต้นและหลักฐานในอนาคต:

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

* มีคนแก้ไขฉันหากแฮ็คนี้ผิด แต่การทดสอบครั้งแรกฉันเห็นว่าใช้งานได้


6
โปรดดูimperialviolet.org/2014/12/08/poodleagain.html "นี่เป็นช่วงเวลาที่ดีที่จะย้ำอีกครั้งว่าทุกอย่างที่น้อยกว่า TLS 1.2 ด้วยชุดเข้ารหัส AEAD นั้นมีการเข้ารหัสลับ"
Neil

3
@Mathew โดยการดูซอร์สโค้ดของServicePointManager.csดูreferenceource.microsoft.com/#System/net/System/Net/…
ลุคฮัตตัน

12
ฉันเห็นคนเรียกร้อง.NET 4.5ค่าเริ่มต้นสำหรับ Tls12 - แต่เมื่อคุณใส่ที่นี่ มันให้คุณเลือกใช้เพื่อSecurityProtocol
Don Cheadle

17
ฉันจะไม่ลงคะแนนคำตอบนี้เนื่องจากให้ข้อมูลที่เป็นประโยชน์มากมาย แต่การใช้งานโปรโตคอล hardcoded ไม่ใช่ความคิดที่ดีเพราะจะ จำกัด แอปพลิเคชันจากการใช้การเข้ารหัสที่ดีที่สุดที่มีอยู่และอาจส่งผลให้เกิดปัญหาด้านความปลอดภัย การเปลี่ยนแปลงรีจิสทรีเพื่อเปลี่ยนพฤติกรรมเริ่มต้นของ. Net เพื่อรองรับโปรโตคอลที่ทันสมัยเป็นที่นิยมอย่างมาก (อย่างไรก็ตามการเปลี่ยนรีจิสทรีจะไม่สามารถใช้งาน SSL v3 ได้เช่นกัน)
AJ Henderson

6
ใน FW 4.6 และ 4.7 ค่าเริ่มต้นจะSecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12เป็นไปตามsupport.microsoft.com/en-us/help/3069494/…
Ian Kemp

68

คุณสามารถลบล้างพฤติกรรมเริ่มต้นในการลงทะเบียนต่อไปนี้:

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

สำหรับรายละเอียดโปรดดูการดำเนินการของServicePointManager


ขอบคุณฉันไม่รู้เกี่ยวกับสิ่งนี้ ฉันจะทดสอบมัน ฉันสร้างสคริปต์ powershel เพื่อตั้งค่า: gist.github.com/lukehutton/ab80d207172a923401b1
ลุคฮัตตั้น

6
การเปลี่ยนรีจิสทรีดูไม่เหมือนทางออกที่ดี หากแอปพลิเคชันต้องการรองรับ TLS1 ดังนั้นแอปพลิเคชันควรคำนึงถึงมัน ไม่ใช่สภาพแวดล้อมการทำงาน มิฉะนั้นอาจเป็นอันตรายต่อแอปพลิเคชั่นอื่นหรือทำให้การติดตั้งและอัปเกรดแอปพลิเคชันของคุณแย่ลง
Mikhail G

13
@ MikailG ค่อนข้างตรงข้าม การเปลี่ยนแปลงรีจิสทรีเป็นวิธีที่ดีกว่า SChannel ให้การเจรจาที่เป็นนามธรรมและคุณต้องการให้แอปพลิเคชันของคุณใช้ระดับความปลอดภัยสูงสุดที่รองรับ การ จำกัด ไว้ในซอฟต์แวร์เป็นผลให้เกิดปัญหาในอนาคตเมื่อมีการออกโปรโตคอลใหม่และซอฟต์แวร์ของคุณไม่สามารถใช้งานได้ มันจะดีถ้ามีตัวเลือกที่จะบอกว่าใช้ดีกว่าโปรโตคอลที่ระบุในซอฟต์แวร์เท่านั้น แต่ไม่มีตัวเลือกสำหรับสิ่งนั้นโดยไม่ป้องกันเวอร์ชันในอนาคตจากการทำงาน ไม่ปิดการใช้งาน SSL v3 ด้วยการเปลี่ยนแปลงนั้น ..
AJ Henderson

13
บรรทัดคำสั่ง: reg add HKLM\SOFTWARE\Microsoft\.NETFramework\v4.0.30319 /v SchUseStrongCrypto /t REG_DWORD /d 1 /reg:64(และ / หรือ/reg:32)
Kevin Smyth

7
@MikhailG: การตั้งค่ารีจิสทรีไม่ได้ป้องกันแอปพลิเคชันที่สนับสนุนโปรโตคอลรุ่นเก่า มันเปลี่ยนเฉพาะค่าเริ่มต้น (ซึ่งรวมถึง tls 1.0 ณ ตอนนี้) นอกจากนี้พฤติกรรมเริ่มต้นใน. Net 4.6+ คือการใช้ crypto ที่แข็งแกร่ง ในกรณีนี้รายการรีจิสทรีนี้จะเป็นประโยชน์ในการปิดการใช้งาน crypto ที่แข็งแกร่งเท่านั้น
Brian

51

สร้างไฟล์ข้อความที่มี.regนามสกุลและเนื้อหาต่อไปนี้:

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

หรือดาวน์โหลดจากแหล่งต่อไปนี้:

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

ดับเบิลคลิกเพื่อติดตั้ง ...


3
ลิงก์ที่คุณระบุมีปัญหาเกี่ยวกับใบรับรอง SSL
NathanAldenSr

แม้ว่าฉันจะเพิ่มคีย์รีจิสทรีเหล่านี้ฉันยังคงมีปัญหานั้นอยู่ ความคิดใด ๆ
Samidjo

@Samidjo - คุณใช้. NET รุ่นใดอยู่ คำตอบของลุคมีรายละเอียดมากกว่าของฉันมาก แต่ดูเหมือนว่าคุณต้องติดตั้ง. NET 4.5 อย่างน้อย นอกจากนี้หากคุณเพิ่งทำการเปลี่ยนแปลงคุณอาจต้องรีไซเคิลแอพพูล เหล่านี้เป็นชนิดของการคาดเดาโดยไม่ต้องรายละเอียดเพิ่มเติมฉันอาจจะสามารถที่จะช่วยเหลืออีกมาก :)
dana

2
แพตช์ที่ใช้เมื่อเร็ว ๆ นี้support.microsoft.com/en-us/help/4019114/…ไปยังเซิร์ฟเวอร์ทำให้แอปพลิเคชัน. net 4.5.2 ของเราล้มเหลวในคำขอ https REST กุญแจเหล่านี้แก้ไขปัญหาของเรา
Kleinux

21

ฉันได้พบว่าเมื่อฉันระบุเฉพาะ TLS 1.2 มันจะยังคงปิดการเจรจากับ 1.1 System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

ฉันระบุสิ่งนี้ในวิธีการเริ่มต้น Global.asax สำหรับแอปพลิเคชันเว็บ. net 4.5 ของฉัน


2
โปรโตคอลความปลอดภัยที่รองรับบนเซิร์ฟเวอร์คืออะไร? ฉันเชื่อว่าเป็นปัจจัยที่นี่ด้วยและอาจเป็น 1.1 เป็นล่าสุดบนเซิร์ฟเวอร์ www.passionatecoder.ca
Ehsan

14
เพิ่มขึ้นเพราะนี่เป็นคำตอบเดียวที่ระบุว่าจะใส่บรรทัดของรหัสที่เป็นโซลูชันอย่างไร
jgerman

1
ลูกค้า (เช่น C # WebClient ของคุณ) และเซิร์ฟเวอร์ (เซิร์ฟเวอร์ API ที่คุณโทรหา) จะเจรจาเพื่อใช้โปรโตคอลสูงสุดที่ทั้งสองฝ่ายสนับสนุน ดังนั้นหากไคลเอ็นต์ของคุณรองรับ TLS 1.2 แต่เซิร์ฟเวอร์เท่านั้น TLS 1.1 - ไคลเอ็นต์จะใช้ TLS 1.1 (เว้นแต่คุณจะลบ TLS 1.1 จากไคลเอนต์ของคุณ - ในกรณีนี้พวกเขาอาจไม่พบโปรโตคอลที่รองรับซึ่งกันและกันและลูกค้าจะผิดพลาด)
Don Cheadle

ต้องเพิ่มโดยใช้ System.Net ใน global.asax.cs
แพทริค

16

รหัสต่อไปนี้จะ:

  • โปรโตคอลที่เปิดใช้งานการพิมพ์
  • พิมพ์โปรโตคอลที่ใช้ได้
  • เปิดใช้งาน TLS1.2 หากแพลตฟอร์มรองรับและหากไม่ได้เปิดใช้งานจะเริ่มต้นด้วย
  • ปิดใช้งาน SSL3 หากเปิดใช้งาน
  • พิมพ์ผลลัพธ์สุดท้าย

ค่าคงที่:

  • 48 คือ SSL3
  • 192 คือ TLS1
  • 768 คือ TLS1.1
  • 3072 คือ TLS1.2

โปรโตคอลอื่น ๆ จะไม่ได้รับผลกระทบ สิ่งนี้ทำให้สิ่งนี้เข้ากันได้กับโปรโตคอลในอนาคต (Tls1.3 ฯลฯ )

รหัส

// 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);

เอาท์พุต

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

ฉันพบปัญหาเมื่อลูกค้าอัปเกรด TLS จาก 1.0 เป็น 1.2 แอปพลิเคชันของฉันใช้. net framework 3.5 และทำงานบนเซิร์ฟเวอร์ ดังนั้นฉันจึงแก้ไขด้วยวิธีนี้:

  1. แก้ไขโปรแกรม

ก่อนที่จะเรียก HttpWebRequest.GetResponse () เพิ่มคำสั่งนี้:

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

ส่วนขยาย 2 DLLs โดยเพิ่ม 2 คลาสใหม่: System.Net และ 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. อัปเดตชุดงานของ Microsoft

ชุดดาวน์โหลด:

  • สำหรับ windows 2008 R2: windows6.1-kb3154518-x64.msu
  • สำหรับ windows 2012 R2: windows8.1-kb3154520-x64.msu

สำหรับชุดดาวน์โหลดและรายละเอียดเพิ่มเติมคุณสามารถดูได้ที่นี่:

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 และเซิร์ฟเวอร์ 2008 R2-SP1


1
เป็นไปได้หรือไม่ที่ SecurityProtocol จะเปลี่ยนโดยไม่ต้องเปลี่ยนซอร์สโค้ด? เช่น machine.config หรือ app.config
ahankendi

1
ว้าว. นั่นคือรางวัลแห่งปีรางวัลวูดู ... ตรงนั้น คุณเขย่าชาน!
granadaCoder

14

กลไกการเปลี่ยนแปลงรีจิสทรีทำงานให้ฉันหลังจากการต่อสู้ ที่จริงแล้วแอปพลิเคชันของฉันทำงานเป็น 32 บิต ดังนั้นฉันต้องเปลี่ยนค่าภายใต้เส้นทาง

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

ประเภทค่าจะต้องเป็น DWORD และค่าที่สูงกว่า 0 การใช้ดีกว่า 1การตั้งค่ารีจิสตรีเพื่อรับแอพ. Net 4.0 ใช้ TLS 1.2 ที่ระบุ. Net 4.5 ติดตั้งในเครื่อง


มันไม่ถูกต้อง สำหรับ. NET 4.5.2 ต้องกำหนดเป็น 1 (หรือสูงกว่า) แต่สำหรับ. NET 4.6 จะไม่สามารถตั้งค่าเป็น 0 ได้ (นั่นคือสามารถยกเลิกการตั้งค่าได้)
Jirka Hanika

โอ้ฉันไม่ได้ทดสอบด้วย. Net 4.6 การค้นพบของฉันอยู่ใน blogpost joymonscode.blogspot.com/2015/08/…
Joy George Kunjikkuru

คีย์รีจิสทรีที่คุณกล่าวถึงควรอ่าน "Wow6432Node" คุณละส่วน "โหนด" ด้วยเหตุผลบางอย่าง ฉันพยายามที่จะแก้ไขคำตอบของคุณ แต่การเปลี่ยนแปลงของฉันเป็นเพียง 4 ตัวอักษรดังนั้นมันจะไม่ยอมให้ฉัน : \
Jeffrey LeCours

ฉันต้องตีกลับ IIS เพื่อให้การตั้งค่านี้ใช้งานเองเป็นค่าเริ่มต้น
Jeff Mitchell

10

ฉันทำงานภายใต้. NET 4.5.2 และฉันไม่พอใจกับคำตอบใด ๆ เหล่านี้ ขณะที่ฉันกำลังพูดคุยกับระบบที่รองรับ TLS 1.2 และการที่เห็นว่าเป็น SSL3, TLS 1.0 และ TLS 1.1 นั้นใช้งานไม่ได้และไม่ปลอดภัยสำหรับการใช้งานฉันไม่ต้องการเปิดใช้งานโปรโตคอลเหล่านี้ ภายใต้ .NET 4.5.2 การ SSL3 และ TLS 1.0 ServicePointManager.SecurityProtocolโปรโตคอลมีทั้งที่เปิดใช้งานโดยค่าเริ่มต้นซึ่งฉันสามารถดูในรหัสโดยการตรวจสอบ ภายใต้. NET 4.7 มีสิ่งใหม่SystemDefaultโหมดโปรโตคอลซึ่งส่งมอบการเลือกโปรโตคอลให้กับระบบปฏิบัติการอย่างชัดเจนโดยที่ฉันเชื่อว่าการใช้รีจิสตรีหรือการตั้งค่าระบบอื่น ๆ นั้นเหมาะสม ที่ดูเหมือนจะไม่ได้รับการสนับสนุนภายใต้. NET 4.5.2 เพื่อประโยชน์ในการเขียนโค้ดที่เข้ากันได้ซึ่งจะทำให้การตัดสินใจถูกต้องแม้ว่า TLS 1.2 จะถูกทำลายอย่างหลีกเลี่ยงไม่ได้ในอนาคตหรือเมื่อฉันอัพเกรดเป็น. NET 4.7+ และมอบความรับผิดชอบมากขึ้นสำหรับการเลือกโปรโตคอลที่เหมาะสมกับระบบปฏิบัติการ ฉันใช้รหัสต่อไปนี้:

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;
}

รหัสนี้จะตรวจจับเมื่อเปิดใช้งานโปรโตคอลที่ไม่ปลอดภัยและในกรณีนี้เราจะลบโปรโตคอลที่ไม่ปลอดภัยเหล่านี้ออก หากไม่มีโปรโตคอลอื่นที่ชัดเจนอยู่เราจะบังคับให้เปิดใช้งาน TLS 1.2 เป็นโปรโตคอลความปลอดภัยที่รู้จักเท่านั้นที่สนับสนุนโดย. NET ณ เวลานี้ รหัสนี้เข้ากันได้กับการส่งต่อเนื่องจากจะคำนึงถึงประเภทโปรโตคอลใหม่ที่ไม่รู้เกี่ยวกับการเพิ่มในอนาคตและจะเล่นได้ดีกับใหม่SystemDefaultสถานะใน. NET 4.7 หมายความว่าฉันจะไม่ต้องไปเยี่ยมรหัสนี้อีกในอนาคต ฉันขอแนะนำอย่างยิ่งให้ใช้วิธีการนี้แทนการเข้ารหัส hard-state ใด ๆ ที่ไม่มีเงื่อนไขมิฉะนั้นคุณจะต้องคอมไพล์ใหม่และแทนที่ไคลเอ็นต์ของคุณด้วยเวอร์ชันใหม่เพื่ออัพเกรดเป็นโปรโตคอลความปลอดภัยใหม่เมื่อ TLS 1.2 เสียอย่างหลีกเลี่ยงไม่ได้หรือเป็นไปได้ว่าคุณจะต้องเปิดโปรโตคอลที่ไม่ปลอดภัยที่มีอยู่เป็นเวลาหลายปีบนเซิร์ฟเวอร์ของคุณทำให้องค์กรของคุณเป็นเป้าหมายในการโจมตี


1
คำตอบนี้ดูเหมือนจะเป็นความคิดที่ดีที่สุดอย่างไรก็ตามถ้าฉันไม่ได้ทำอะไรฉันไม่แน่ใจว่ามันจะเข้ากันได้เมื่อใดก็ตามที่ TLS 1.2 หยุดพัก จากสิ่งที่ฉันเห็นในแอป. NET 4.7.2 ของฉันSecurityProtocolType.SystemDefaultค่าสถานะจะประเมินเป็น0ดังนั้นการตรวจสอบif (securityProtocols == 0)ด้วยค่าบิตรวมหรือการตั้งค่าสถานะสำหรับ TLS 1.2 จะรวม TLS 1.2 เสมอแม้ว่าจะเป็น "ตัวแบ่ง" ใช่ไหม ไม่ใช่การถ่ายภาพที่คมชัดที่นี่ ฉันพยายามค้นหาเส้นทางที่ดีที่สุดอย่างแท้จริง
Griswald_911

if (!Enum.IsDefined(typeof(SecurityProtocolType), 0) && securityProtocols == 0) { securityProtocols |= SecurityProtocolType.Tls12; }ฉันได้มีการปรับเปลี่ยนรหัสของคุณรวมถึงนี้และจะปรากฏในการทำงานและจะเข้ากันได้ไปข้างหน้า:
Griswald_911

@ Griswald_911 ฉันมีรหัสที่คล้ายกันในแอปพลิเคชันคอนโซล 4.7.2 ของฉันและฉันพบว่าบรรทัดนี้securityProtocols |= SecurityProtocolType.Tls12;(โดยไม่ต้องบล็อกถ้า) ไม่รักษา SystemDefault, securityProtocols เพียง TLS2 หลังจากนั้น ดังนั้นคุณหมายถึงเมื่อค่าเป็น SystemDefault ไม่ควรปรับปรุงค่าใด ๆ เกี่ยวกับความเข้ากันได้ไปข้างหน้าคุณสมมติว่าระบบปฏิบัติการจะดูแลการเปิดใช้งานโปรโตคอลที่ใหม่กว่าเช่น TLS 1.3 หรือไม่
ยาง

@Yang - ถูกต้อง บรรทัดsecurityProtocols |= SecurityProtocolType.Tls12;' will add TLS 1.2, but because the SecurityProtocolType` enum มี[Flags]แอตทริบิวต์และค่าการแจงนับ SystemDefault คือ0ค่า SystemDefault จะถูกปล้นแม้ว่าจะถูกตั้งค่าไว้ก่อนหน้านี้ก็ตาม ผลลัพธ์ที่ได้คือคุณสามารถตั้งค่าเป็นSevicePointManager.SecurityProtocol 0 หรือรวมกันของค่าการแจงนับอื่น ๆ หากคุณตั้งค่าเป็น SystemDefault โดยทั่วไปคุณจะไม่ระบุโปรโตคอลด้วยตนเองและให้ระบบปฏิบัติการตัดสินใจ
Griswald_911

1
@Yang - ประเด็นคือหลังจากตั้งค่าเป็น SystemDefault แล้วแอปของคุณควรใช้สิ่งที่ระบบปฏิบัติการระบุ - ซึ่งเป็น TLS 1.2 ใน Windows เวอร์ชันล่าสุด 10. แนวคิดคือในอนาคตเมื่อ TLS 1.3 กลายเป็น มาตรฐานคุณไม่จำเป็นต้องปรับเปลี่ยนแอปพลิเคชันของคุณเพื่อรับฟังก์ชั่นนั้น ดูเอกสารประกอบที่นี่โดยที่ SystemDefault "อนุญาตให้ระบบปฏิบัติการเลือกโปรโตคอลที่ดีที่สุดที่จะใช้และเพื่อป้องกันโปรโตคอลที่ไม่ปลอดภัย"
Griswald_911

6

Microsoft เพิ่งเผยแพร่แนวทางปฏิบัติที่ดีที่สุดเกี่ยวกับเรื่องนี้ https://docs.microsoft.com/en-us/dotnet/framework/network-programming/tls

สรุป

เป้าหมาย. Net Framework 4.7 ลบการตั้งค่ารหัสใด ๆ ที่ SecurityProtocol ดังนั้นระบบปฏิบัติการจะช่วยให้คุณมั่นใจได้ว่าจะใช้โซลูชันที่ปลอดภัยที่สุด

หมายเหตุ: คุณจะต้องตรวจสอบให้แน่ใจว่ารองรับและเปิดใช้งาน TLS เวอร์ชันล่าสุดในระบบปฏิบัติการของคุณ

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

สำหรับข้อมูลเพิ่มเติมและกรอบเก่า ๆ โปรดดูที่ลิงก์ MS


3
ปัญหาคือว่า tls 1.1 และ tls 1.2 จะไม่ทำงานบน Windows 7 และ Server 2008 หากคุณปฏิบัติตามแนวทาง (การรักษาความปลอดภัย SecurityProtocolType.SystemDefault) เพราะพวกเขาไม่ได้ "เปิดใช้งาน" (สิ่งที่หมายถึง) ในระบบปฏิบัติการเหล่านี้โดยไม่มีการเปลี่ยนแปลงรีจิสทรี สิ่งนี้ทำให้ SystemDefault ในทางปฏิบัติถูกทำลายโดยการออกแบบ Microsoft ทำให้สิ่งนี้สับสนมาก
osexpert

เป็นคนที่ดีขอบคุณ @expert จับได้ดี ฉันได้แก้ไขคำตอบเพื่อรวมข้อมูลเกี่ยวกับระบบปฏิบัติการที่รองรับดังนั้นจึงไม่มีเรื่องที่น่าประหลาดใจสำหรับผู้ที่ใช้ระบบปฏิบัติการรุ่นเก่าที่เพิ่งตั้งเป้าหมาย 4.7 ไม่เพียงพอ
JohnLBevan

1
หมายเหตุ: นอกจากนี้ยังมี KB เพื่อเปิดใช้งานโพรโทคอลที่ใหม่กว่าในบางระบบปฏิบัติการ: support.microsoft.com/en-my/help/3140245/…
JohnLBevan

1
หากการตั้งค่ารีจิสทรีไม่ใช่ตัวเลือกฉันคิดว่านี่เป็นทางออกที่ดีที่สุดสำหรับ. 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

เพื่อความสมบูรณ์นี่คือสคริปต์ Powershell ที่ตั้งค่ารีจิสตรีคีย์ดังกล่าว:

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

ทางเลือกอื่นในการเข้ารหัสแบบหนักServicePointManager.SecurityProtocolหรือคีย์SchUseStrongCryptoอย่างชัดเจนดังที่กล่าวไว้ข้างต้น:
คุณสามารถบอกให้. NET ใช้การตั้งค่าเริ่มต้น SCHANNEL ด้วยคีย์ SystemDefaultTlsVersions
เช่น:

[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

ทางออกที่ดีที่สุดสำหรับปัญหานี้ดูเหมือนจะเป็นการอัพเกรดเป็นอย่างน้อย. NET 4.6 หรือใหม่กว่าซึ่งจะเลือกโปรโตคอลที่รัดกุมเช่นเดียวกับรหัสที่แข็งแกร่งโดยอัตโนมัติ

หากคุณไม่สามารถอัพเกรดเป็น. NET 4.6 ได้คำแนะนำในการตั้งค่า

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

และการใช้การตั้งค่ารีจิสทรี:

HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft.NETFramework \ v4.0.30319 - SchUseStrongCrypto = DWORD เป็น 1 HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft.NETFramework \ v4.0.30319 - SchUseStrongCrypto = DWORD 1

ผลลัพธ์ในการใช้อย่างอื่นที่ไม่ใช่ TLS 1.0 และรหัสลับที่แข็งแกร่ง

ในการทดสอบของฉันเฉพาะการตั้งค่าใน Wow6432Node เท่านั้นที่สร้างความแตกต่างแม้ว่าแอปพลิเคชันทดสอบของฉันจะถูกสร้างขึ้นสำหรับ CPU ใด ๆ ก็ตาม


Clarification: คุณต้องตั้งค่า SevicePointManager.SecurityProtocol หรือตั้งค่ารีจิสทรีเท่านั้น ไม่จำเป็นต้องทำทั้งสองอย่าง สำหรับแอปพลิเคชันของฉันฉันเลือกที่จะตั้งค่า ServicePointManager.SecurityProtocol เหตุผลของฉันคือการตั้งค่ารีจิสทรีส่งผลกระทบต่อทั้งเครื่องและฉันไม่ต้องการให้แอปพลิเคชันของบุคคลอื่นแตกเพราะขึ้นอยู่กับ TLS 1.0
GWC

1

ตามแนวทางปฏิบัติที่ดีที่สุดของ Transport Layer Security (TLS) ด้วย. NET Framework : เพื่อให้แน่ใจว่าแอพพลิเคชั่น. NET Framework ยังคงปลอดภัยรุ่น TLS ไม่ควรถูกเข้ารหัส แทนที่จะตั้งค่ารีจิสตรีคีย์: 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

หากคุณสามารถใช้. NET 4.7.1 หรือใหม่กว่านั้นก็จะใช้ TLS 1.2 เป็นโปรโตคอลขั้นต่ำตามความสามารถของระบบปฏิบัติการ ตามคำแนะนำของ 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

สำหรับคีย์: HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft.NETFramework \ v4.0.30319 ค่า: SchUseStrongCrypto

คุณต้องตั้งค่าเป็น 1


5
ฉันคิดว่าคุณกำลังถูกลดระดับลงเพราะเป็นคำตอบเดียวกันกับ @Jira Mares แต่มีรายละเอียดน้อยกว่า
Stuart Siegler
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.