การตรวจสอบความถูกต้องล้มเหลวเนื่องจากบุคคลระยะไกลปิดสตรีมการขนส่ง


87

ฉันกำลังพัฒนาไคลเอ็นต์ TCP เพื่อเชื่อมต่อเซิร์ฟเวอร์ OpenSSL ด้วยการตรวจสอบใบรับรอง ฉันใช้ไฟล์. crt และ. key ที่แชร์โดยทีมเซิร์ฟเวอร์ ใบรับรองเหล่านี้สร้างขึ้นโดยคำสั่ง OpenSSL

ฉันใช้SslStreamวัตถุในการตรวจสอบไคลเอนต์ Tcp โดยเรียกSslStream.AuthenticateAsClientวิธีโดยผ่านเซิร์ฟเวอร์IP, และSslProtocols.Ssl3X509CertificateCollection

ฉันได้รับข้อผิดพลาดต่อไปนี้:

การรับรองความถูกต้องล้มเหลวเนื่องจากฝ่ายระยะไกลปิดสตรีมการขนส่ง


2
SslProtocols.Ssl3ลักษณะเช่นนี้มีปัญหาในวันที่โพสต์พุดเดิ้ลไปนี้: SslProtocols.Tlsบางทีคุณอาจจะลอง ใน. Net 4.5 ขึ้นไปคุณยังสามารถใช้Tls11หรือTls12. ดูSslProtocols การแจงนับ คุณอาจมีปัญหาอื่น ๆ
jww


ขอบคุณ. ปัญหาของฉันได้รับการแก้ไขโดยการแนบใบรับรองจากเส้นทางจริงของใบรับรองและรหัสผ่านแทนการค้นหาชื่อเรื่องใบรับรองจากที่เก็บใบรับรองของ windows
Odelu

ตอนนี้ฉันสามารถรับผลลัพธ์จาก SslProtocols ทั้งหมด (SSL3, Tls1 และ Tls2) ขอบคุณสำหรับการตอบกลับ
Odelu

@Odelu คุณแก้ไขปัญหาอย่างไร ในฝั่งไคลเอ็นต์หรือฝั่งเซิร์ฟเวอร์?

คำตอบ:


155

ฉันขอแนะนำไม่ให้ จำกัด SecurityProtocol ไว้ที่ TLS 1.1

วิธีแก้ปัญหาที่แนะนำคือการใช้

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

อีกทางเลือกหนึ่งคือเพิ่มคีย์รีจิสทรีต่อไปนี้:

Key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319 
Value: SchUseStrongCrypto 

เป็นที่น่าสังเกตว่า. NET 4.6 จะใช้โปรโตคอลที่ถูกต้องตามค่าเริ่มต้นและไม่ต้องการโซลูชันใดวิธีหนึ่ง


6
ว้าวคุณเพิ่งแยกแยะปัญหาของฉัน - ฉันพยายามทุกอย่าง - แล้วก็มาเห็นโน้ตบนเฟรมเวิร์กที่นี่ เพิ่งเปลี่ยนเป็น 4.6.1 (ใช้ 4.5) หวังว่าปัญหาจะเกิดจากเฟรมเวิร์กอาจใช้โปรโตคอลความปลอดภัยที่ไม่ถูกต้อง - และบิงโกการเชื่อมต่อของฉันไม่ถูกปฏิเสธและฉันกำลังรับข้อมูลของฉัน!
Veverke

7
สิ่งสำคัญคือSystem.Net.ServicePointManager.SecurityProtocol = ...ต้องดำเนินการก่อนสร้างคำขอ
Tonatio

2
เวอร์ชันกรอบเป้าหมายที่อัปเดตเป็น 4.6.1 ช่วยชีวิตฉัน :-)
Awais

กรอบของฉันตั้งไว้ที่ 4.6.2 บางทีฉันอาจต้องใช้โซลูชัน TLS แทน
Luminous

ฉันใช้ 4.7.2 Framework และไซต์ที่ฉันส่งคำขอใช้ TLS 1.2 แต่เหมือน 6 ​​คำขอจาก 10 ฉันได้รับข้อผิดพลาดนี้ ความคิดใด ๆ
Davit Mikuchadze

16

หากคุณต้องการใช้. net เวอร์ชันเก่าให้สร้างแฟล็กของคุณเองแล้วแคสต์

    //
    // Summary:
    //     Specifies the security protocols that are supported by the Schannel security
    //     package.
    [Flags]
    private enum MySecurityProtocolType
    {
        //
        // Summary:
        //     Specifies the Secure Socket Layer (SSL) 3.0 security protocol.
        Ssl3 = 48,
        //
        // Summary:
        //     Specifies the Transport Layer Security (TLS) 1.0 security protocol.
        Tls = 192,
        //
        // Summary:
        //     Specifies the Transport Layer Security (TLS) 1.1 security protocol.
        Tls11 = 768,
        //
        // Summary:
        //     Specifies the Transport Layer Security (TLS) 1.2 security protocol.
        Tls12 = 3072
    }
    public Session()
    {
        System.Net.ServicePointManager.SecurityProtocol = (SecurityProtocolType)(MySecurityProtocolType.Tls12 | MySecurityProtocolType.Tls11 | MySecurityProtocolType.Tls);
    }

1
คุณไม่จำเป็นต้องใช้คลาสของคุณเองคุณสามารถแคสต์จำนวนเต็มไปที่ SecurityProtocolType ได้โดยตรงServicePointManager.SecurityProtocol = (SecurityProtocolType) 48 | (SecurityProtocolType) 192 | (SecurityProtocolType) 768 | (SecurityProtocolType) 3072;
Yan F.


8
using (var client = new HttpClient(handler))
            {
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
                var response = await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, apiEndPoint)).ConfigureAwait(false);
                await response.Content.ReadAsStringAsync().ConfigureAwait(false);
            }

สิ่งนี้ได้ผลสำหรับฉัน


1
บิตวิกฤตคือบรรทัดต่อไปนี้: ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls; คำตอบนี้ดีมากเพราะมันแสดงให้เห็นว่าเส้นนั้นควรอยู่ตรงไหนภายในกรณีการใช้งานทั่วไป
Nick Painter

5

ฉันพบข้อความแสดงข้อผิดพลาดเดียวกันในขณะที่ใช้ ChargifyNET.dll เพื่อสื่อสารกับ Chargify API การเพิ่มchargify.ProtocolType = SecurityProtocolType.Tls12;ในการกำหนดค่าช่วยแก้ปัญหาให้ฉันได้

นี่คือข้อมูลโค้ดฉบับสมบูรณ์:

public ChargifyConnect GetChargifyConnect()
{
    var chargify = new ChargifyConnect();
    chargify.apiKey = ConfigurationManager.AppSettings["Chargify.apiKey"];
    chargify.Password = ConfigurationManager.AppSettings["Chargify.apiPassword"];
    chargify.URL = ConfigurationManager.AppSettings["Chargify.url"];

    // Without this an error will be thrown.
    chargify.ProtocolType = SecurityProtocolType.Tls12;

    return chargify;
}

2

สำหรับ VB.NET คุณสามารถวางสิ่งต่อไปนี้ก่อนคำขอทางเว็บของคุณ:

Const _Tls12 As SslProtocols = DirectCast(&HC00, SslProtocols)
Const Tls12 As SecurityProtocolType = DirectCast(_Tls12, SecurityProtocolType)
ServicePointManager.SecurityProtocol = Tls12

สิ่งนี้ช่วยแก้ปัญหาความปลอดภัยของฉันบน. NET 3.5


0

สิ่งนี้เกิดขึ้นกับฉันเมื่อปลายทางคำขอเว็บเปลี่ยนไปยังเซิร์ฟเวอร์อื่นที่ยอมรับคำขอ TLS1.2 เท่านั้น พยายามหลายครั้งมากที่พบใน Stackoverflow เช่น

  1. คีย์รีจิสทรี
  2. เพิ่ม:
    System.Net.ServicePointManager.SecurityProtocol | = System.Net.SecurityProtocolType.Tls12; เป็น Global.ASX OnStart,
  3. เพิ่มใน Web.config
  4. อัปเดต. Net framework เป็น 4.7.2 ยังคงได้รับ Exception เหมือนเดิม

ข้อยกเว้นที่ได้รับไม่ได้ทำให้เกิดความยุติธรรมกับปัญหาที่แท้จริงที่ฉันกำลังเผชิญและไม่พบความช่วยเหลือจากผู้ให้บริการ

ในการแก้ปัญหานี้ฉันต้องเพิ่ม Cipher Suite ใหม่TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 ฉันใช้ IIS Crypto 2.0 Tool จากที่นี่ดังที่แสดงด้านล่าง

ป้อนคำอธิบายภาพที่นี่

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