C # ละเว้นข้อผิดพลาดของใบรับรองหรือไม่


159

ฉันได้รับข้อผิดพลาดต่อไปนี้ระหว่างการร้องขอบริการเว็บไปยังบริการเว็บระยะไกล:

ไม่สามารถสร้างความสัมพันธ์ที่เชื่อถือได้สำหรับช่องทางที่ปลอดภัยของ SSL / TLS ---> System.Security.Authentication.AuthenticationException: ใบรับรองระยะไกลไม่ถูกต้องตามขั้นตอนการตรวจสอบความถูกต้อง

อย่างไรก็ตามมีการละเว้นข้อผิดพลาดนี้และดำเนินการต่อหรือไม่

ดูเหมือนว่าใบรับรองระยะไกลไม่ได้ลงนาม

ไซต์ที่ฉันเชื่อมต่ออยู่www.czebox.cz- ดังนั้นโปรดเยี่ยมชมไซต์และสังเกตว่าแม้แต่เบราว์เซอร์ก็มีข้อยกเว้นด้านความปลอดภัย

คำตอบ:


341

เพิ่มตัวจัดการการตรวจสอบความถูกต้องใบรับรอง การกลับมาtrueจะช่วยให้ละเลยข้อผิดพลาดในการตรวจสอบความถูกต้อง:

ServicePointManager
    .ServerCertificateValidationCallback += 
    (sender, cert, chain, sslPolicyErrors) => true;

6
สิ่งนี้มีประโยชน์มากกว่าที่ปรากฏในครั้งแรก ฉันพบปัญหา OP จากการใช้ Managed Exchanged Web Services (EWS) ฉันคิดว่าฉันไม่สามารถใช้คำตอบนี้ได้เนื่องจากฉันไม่สามารถเข้าถึงการโทร SOAP ระดับต่ำที่ทำโดยไลบรารีที่จัดการนั้น แต่เมื่อฉันดูอีกครั้งฉันก็รู้ว่า ServicePointManager ยืนหยัดอยู่ได้ ดังนั้นฉันจึงเพิ่มการโทรกลับด้านบนก่อนที่จะเริ่มต้น ExchangeService และทำงานได้อย่างมีเสน่ห์
Mark Meuer

2
นี่คือตัวอย่างของวิธีการใช้บายพาสทั่วโลก สำหรับพวกเราทุกคนไปสู่การปฏิบัติที่ไม่ดี (บางครั้งคุณไม่มีทางเลือก) jasig.275507.n4.nabble.com/…
snowYetis

1
ขอบคุณมากที่ช่วยแก้ไขปัญหาชั่วคราว เพิ่มรหัสนี้ใน Startup.cs ใน Web Api
Sivalingaamorthy

2
@ MarkMeuer เกือบจะยอมแพ้ในการแก้ปัญหานี้สำหรับปัญหา EWS API ของฉัน แต่แล้วฉันก็เห็นความคิดเห็นของคุณ
Mahen

7
@MiguelVeloso คุณสามารถลงคะแนนได้อย่างอิสระ แต่โปรดจำไว้ว่าทั้งคำถามและคำตอบจะไม่พูดถึงด้านความปลอดภัยของเรื่องนี้ หัวข้อคือ "วิธีการเพิกเฉยต่อข้อผิดพลาดในการตรวจสอบอย่างชัดเจน" ไม่ใช่ "ทำไมเราควรทำ / ไม่ทำเช่นนี้" ซึ่งเป็นหัวข้อที่แตกต่างกันโดยสิ้นเชิง เข้าสู่การอภิปรายว่าทำไม OP ไม่ควรทำแค่โคลนเท่านั้นเนื่องจากผู้วิจารณ์ได้ชี้ให้เห็นว่ามีหลายกรณีที่คุณจะทำเช่นนี้ ดังนั้นเราจึงยึดหัวข้อและแก้ไขปัญหา
Peter Lillevold

40

การอนุญาตใบรับรองทั้งหมดนั้นมีประสิทธิภาพมาก แต่ก็อาจเป็นอันตรายได้เช่นกัน หากคุณต้องการอนุญาตเฉพาะใบรับรองที่ถูกต้องรวมทั้งใบรับรองบางอย่างก็สามารถทำได้เช่นนี้

.Net core:

using (var httpClientHandler = new HttpClientHandler())
{
    httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, sslPolicyErrors) => {
        if (sslPolicyErrors == SslPolicyErrors.None)
        {
            return true;   //Is valid
        }

        if (cert.GetCertHashString() == "99E92D8447AEF30483B1D7527812C9B7B3A915A7")
        {
            return true;
        }
        return false;
    };
    using (var httpClient = new HttpClient(httpClientHandler))
    {
        var httpResponse = httpClient.GetAsync("https://example.com").Result;
    }
}

กรอบสุทธิ

System.Net.ServicePointManager.ServerCertificateValidationCallback += delegate (
    object sender,
    X509Certificate cert,
    X509Chain chain,
    SslPolicyErrors sslPolicyErrors)
{
    if (sslPolicyErrors == SslPolicyErrors.None)
    {
        return true;   //Is valid
    }

    if (cert.GetCertHashString() == "99E92D8447AEF30483B1D7527812C9B7B3A915A7")
    {
        return true;
    }

    return false;
};

ปรับปรุง:

วิธีรับcert.GetCertHashString()คุณค่าใน Chrome:

คลิกที่SecureหรือNot Secureในแถบที่อยู่

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

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

จากนั้นคลิกที่ใบรับรอง -> รายละเอียด -> รหัสประจำตัวและคัดลอกค่า cert.GetCertHashString().ToLower()โปรดจำไว้ว่าจะทำอย่างไร

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


3
@MiguelVeloso เห็นด้วยอย่างสมบูรณ์ วิธีนี้ช่วยให้ข้ามการตรวจสอบ (หวังว่า) หนึ่งหรือสองใบรับรองโดยไม่ลดทอนความปลอดภัยอย่างสมบูรณ์
Kemuel Sanchez

ฉันจะได้รับHash Stringใบรับรองอย่างไร
Kiquenet

@Kiquenet ทั้งแก้ปัญหารหัสและวิ่งcert.GetCertHashString()จากImmediate windowหรือการตรวจสอบใบรับรองThumbprintในเบราว์เซอร์ของคุณหรือMMCหากมีการติดตั้งภายใน
Ogglas

เซิร์ฟเวอร์อยู่ในการควบคุมของเรามันยังปลอดภัยที่จะใช้รหัสของ @ Ogglas ในการผลิตหรือไม่? การใช้ TLS / SSL สามารถหยุดการโจมตีแบบคนกลางได้หรือไม่?
Pingpong

ขอบคุณความช่วยเหลือที่ยิ่งใหญ่มาก
Wowo Ot

30

IgnoreBadCertificates วิธี:

//I use a method to ignore bad certs caused by misc errors
IgnoreBadCertificates();

// after the Ignore call i can do what ever i want...
HttpWebRequest request_data = System.Net.WebRequest.Create(urlquerystring) as HttpWebRequest;

/*
and below the Methods we are using...
*/

/// <summary>
/// Together with the AcceptAllCertifications method right
/// below this causes to bypass errors caused by SLL-Errors.
/// </summary>
public static void IgnoreBadCertificates()
{
    System.Net.ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(AcceptAllCertifications);
}  

/// <summary>
/// In Short: the Method solves the Problem of broken Certificates.
/// Sometime when requesting Data and the sending Webserverconnection
/// is based on a SSL Connection, an Error is caused by Servers whoes
/// Certificate(s) have Errors. Like when the Cert is out of date
/// and much more... So at this point when calling the method,
/// this behaviour is prevented
/// </summary>
/// <param name="sender"></param>
/// <param name="certification"></param>
/// <param name="chain"></param>
/// <param name="sslPolicyErrors"></param>
/// <returns>true</returns>
private static bool AcceptAllCertifications(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certification, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors)
{
    return true;
} 

2
ฉันต้องเพิ่มอีกหนึ่งบรรทัดเพื่อให้สิ่งนี้ใช้งานได้กับรหัสของฉัน (ฉันใช้ websocket4net) System.Net.ServicePointManager.CheckCertificateRevocationList = false; ทันทีหลังจากตั้งค่าการเรียกกลับการตรวจสอบความถูกต้องใบรับรองเซิร์ฟเวอร์
kalyanswaroop

24

สาเหตุที่ทำให้เกิดความล้มเหลวไม่ใช่เพราะไม่ได้ลงชื่อ แต่เป็นเพราะใบรับรองรูทไม่ได้รับความเชื่อถือจากลูกค้าของคุณ แทนที่จะปิดการตรวจสอบความถูกต้องของ SSL วิธีการทางเลือกอื่นก็คือการเพิ่มใบรับรอง CA root ลงในรายการ CA ที่แอปของคุณเชื่อถือ

นี่คือใบรับรองรูท CA ที่แอปของคุณไม่เชื่อถือ

-----BEGIN CERTIFICATE-----
MIIFnDCCBISgAwIBAgIBZDANBgkqhkiG9w0BAQsFADBbMQswCQYDVQQGEwJDWjEs
MCoGA1UECgwjxIxlc2vDoSBwb8WhdGEsIHMucC4gW0nEjCA0NzExNDk4M10xHjAc
BgNVBAMTFVBvc3RTaWdudW0gUm9vdCBRQ0EgMjAeFw0xMDAxMTkwODA0MzFaFw0y
NTAxMTkwODA0MzFaMFsxCzAJBgNVBAYTAkNaMSwwKgYDVQQKDCPEjGVza8OhIHBv
xaF0YSwgcy5wLiBbScSMIDQ3MTE0OTgzXTEeMBwGA1UEAxMVUG9zdFNpZ251bSBS
b290IFFDQSAyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoFz8yBxf
2gf1uN0GGXknvGHwurpp4Lw3ZPWZB6nEBDGjSGIXK0Or6Xa3ZT+tVDTeUUjT133G
7Vs51D6z/ShWy+9T7a1f6XInakewyFj8PT0EdZ4tAybNYdEUO/dShg2WvUyfZfXH
0jmmZm6qUDy0VfKQfiyWchQRi/Ax6zXaU2+X3hXBfvRMr5l6zgxYVATEyxCfOLM9
a5U6lhpyCDf2Gg6dPc5Cy6QwYGGpYER1fzLGsN9stdutkwlP13DHU1Sp6W5ywtfL
owYaV1bqOOdARbAoJ7q8LO6EBjyIVr03mFusPaMCOzcEn3zL5XafknM36Vqtdmqz
iWR+3URAUgqE0wIDAQABo4ICaTCCAmUwgaUGA1UdHwSBnTCBmjAxoC+gLYYraHR0
cDovL3d3dy5wb3N0c2lnbnVtLmN6L2NybC9wc3Jvb3RxY2EyLmNybDAyoDCgLoYs
aHR0cDovL3d3dzIucG9zdHNpZ251bS5jei9jcmwvcHNyb290cWNhMi5jcmwwMaAv
oC2GK2h0dHA6Ly9wb3N0c2lnbnVtLnR0Yy5jei9jcmwvcHNyb290cWNhMi5jcmww
gfEGA1UdIASB6TCB5jCB4wYEVR0gADCB2jCB1wYIKwYBBQUHAgIwgcoagcdUZW50
byBrdmFsaWZpa292YW55IHN5c3RlbW92eSBjZXJ0aWZpa2F0IGJ5bCB2eWRhbiBw
b2RsZSB6YWtvbmEgMjI3LzIwMDBTYi4gYSBuYXZhem55Y2ggcHJlZHBpc3UvVGhp
cyBxdWFsaWZpZWQgc3lzdGVtIGNlcnRpZmljYXRlIHdhcyBpc3N1ZWQgYWNjb3Jk
aW5nIHRvIExhdyBObyAyMjcvMjAwMENvbGwuIGFuZCByZWxhdGVkIHJlZ3VsYXRp
b25zMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQW
BBQVKYzFRWmruLPD6v5LuDHY3PDndjCBgwYDVR0jBHwweoAUFSmMxUVpq7izw+r+
S7gx2Nzw53ahX6RdMFsxCzAJBgNVBAYTAkNaMSwwKgYDVQQKDCPEjGVza8OhIHBv
xaF0YSwgcy5wLiBbScSMIDQ3MTE0OTgzXTEeMBwGA1UEAxMVUG9zdFNpZ251bSBS
b290IFFDQSAyggFkMA0GCSqGSIb3DQEBCwUAA4IBAQBeKtoLQKFqWJEgLNxPbQNN
5OTjbpOTEEkq2jFI0tUhtRx//6zwuqJCzfO/KqggUrHBca+GV/qXcNzNAlytyM71
fMv/VwgL9gBHTN/IFIw100JbciI23yFQTdF/UoEfK/m+IFfirxSRi8LRERdXHTEb
vwxMXIzZVXloWvX64UwWtf4Tvw5bAoPj0O1Z2ly4aMTAT2a+y+z184UhuZ/oGyMw
eIakmFM7M7RrNki507jiSLTzuaFMCpyWOX7ULIhzY6xKdm5iQLjTvExn2JTvVChF
Y+jUu/G0zAdLyeU4vaXdQm1A8AEiJPTd0Z9LAxL6Sq2iraLNN36+NyEK/ts3mPLL

-----END CERTIFICATE-----

คุณสามารถถอดรหัสและดูใบรับรองนี้โดยใช้

ตัวถอดรหัสใบรับรองนี้หรือตัวถอดรหัสใบรับรองอื่น


ใช่ นี่เป็นกรณีของฉัน แต่ฉันจะเพิ่มใบรับรองบน ​​Azure โดยไม่ใช้ VM ได้อย่างไร ฉันสามารถใช้ X509Store API ได้หรือไม่ พรุ่งนี้ฉันจะลองทำดู แต่ยินดีต้อนรับข้อมูลใด ๆ ที่นี่
João Antunes

7

หากต้องการปิดใช้งานการตรวจสอบความถูกต้องใบรับรอง SSL ในการกำหนดค่าไคลเอ็นต์

<behaviors>
   <endpointBehaviors>
      <behavior name="DisableSSLCertificateValidation">
         <clientCredentials>
             <serviceCertificate>
                <sslCertificateAuthentication certificateValidationMode="None" />
              </serviceCertificate>
           </clientCredentials>
        </behavior>

web.configนี้หรือไม่ ทางเลือกใด ๆ สำหรับ ASP.NET Core?
Shimmy Weitzhandler

5

รหัสนี้ใช้ได้สำหรับฉัน ฉันต้องเพิ่ม TLS2 เพราะนั่นคือสิ่งที่ URL ที่ฉันสนใจใช้อยู่

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
ServicePointManager.ServerCertificateValidationCallback +=
    (sender, cert, chain, sslPolicyErrors) => { return true; };
using (var client = new HttpClient())
{
    client.BaseAddress = new Uri(UserDataUrl);
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(new
      MediaTypeWithQualityHeaderValue("application/json"));
    Task<string> response = client.GetStringAsync(UserDataUrl);
    response.Wait();

    if (response.Exception != null)
    {
         return null;
    }

    return JsonConvert.DeserializeObject<UserData>(response.Result);
}

3

บายพาสใบรับรอง SSL ....

        HttpClientHandler clientHandler = new HttpClientHandler();
        clientHandler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; };

        // Pass the handler to httpclient(from you are calling api)
        var client = new HttpClient(clientHandler)

2

หากคุณใช้ซ็อกเก็ตโดยตรงและกำลังตรวจสอบสิทธิ์ในฐานะลูกค้าวิธีการติดต่อกลับของ Service Point Manager จะไม่ทำงาน นี่คือสิ่งที่ได้ผลสำหรับฉัน กรุณาใช้สำหรับวัตถุประสงค์ในการทดสอบเท่านั้น

var activeStream = new SslStream(networkStream, false, (a, b, c, d) => { return true; });
await activeStream.AuthenticateAsClientAsync("computer.local");

กุญแจสำคัญในที่นี้คือการให้การเรียกกลับการตรวจสอบความถูกต้องของใบรับรองระยะไกลใน Constructor ของสตรีม SSL


1

หากต้องการขยายโพสต์ของ BIGNUM ต่อไป - โดยหลักแล้วคุณต้องการโซลูชันที่จะจำลองสภาพที่คุณเห็นในการผลิตและการแก้ไขรหัสของคุณจะไม่ทำเช่นนั้นและอาจเป็นอันตรายหากคุณลืมนำรหัสออกก่อนที่จะปรับใช้

คุณจะต้องมีใบรับรองที่ลงนามเองบางประเภท หากคุณรู้ว่าคุณกำลังทำอะไรอยู่คุณสามารถใช้ไบนารี BIGNUM ที่โพสต์ได้ แต่ถ้าไม่ใช่คุณสามารถไปหาใบรับรองได้ หากคุณใช้ IIS Express คุณจะมีหนึ่งในนั้นอยู่แล้วคุณจะต้องค้นหามัน เปิด Firefox หรือเบราว์เซอร์อะไรก็ได้ที่คุณชอบแล้วไปที่เว็บไซต์ dev ของคุณ คุณควรจะสามารถดูข้อมูลใบรับรองจากแถบ URL และขึ้นอยู่กับเบราว์เซอร์ของคุณคุณควรจะสามารถส่งออกใบรับรองไปยังไฟล์

ถัดไปเปิด MMC.exe และเพิ่มสแน็ปอินใบรับรอง นำเข้าไฟล์ใบรับรองของคุณไปยังที่เก็บผู้ออกใบรับรองหลักที่เชื่อถือได้และนั่นคือทั้งหมดที่คุณต้องการ เป็นเรื่องสำคัญที่จะต้องตรวจสอบให้แน่ใจว่าได้เข้าไปในร้านนั้นไม่ใช่ร้านอื่น ๆ เช่น 'ส่วนบุคคล' หากคุณไม่คุ้นเคยกับ MMC หรือใบรับรองมีเว็บไซต์มากมายพร้อมข้อมูลวิธีการทำเช่นนี้

ตอนนี้คอมพิวเตอร์ของคุณโดยรวมจะเชื่อถือใบรับรองใด ๆ ที่สร้างขึ้นเองและคุณไม่จำเป็นต้องเพิ่มรหัสเพื่อจัดการกับสิ่งนี้เป็นพิเศษ เมื่อคุณย้ายไปยังการผลิตจะยังคงทำงานต่อไปหากคุณมีใบรับรองที่ถูกต้องติดตั้งอยู่ที่นั่น อย่าทำสิ่งนี้บนเซิร์ฟเวอร์ที่ใช้งานจริงซึ่งอาจไม่ดีและไม่สามารถใช้งานได้กับลูกค้ารายอื่นนอกเหนือจากที่อยู่ในเซิร์ฟเวอร์


1

สิ่งนี้ใช้ได้กับ. Net Core โทรหาลูกค้าสบู่ของคุณ:

client.ClientCredentials.ServiceCertificate.SslCertificateAuthentication =
                new X509ServiceCertificateAuthentication()
                {
                    CertificateValidationMode = X509CertificateValidationMode.None,
                    RevocationMode = X509RevocationMode.NoCheck
                };  
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.