Ssl कब सर्टिफिकेट चेक को नजरअंदाज करें


132

मैं Https संसाधन के अनुरोध पर प्रमाण पत्र की जांच को अनदेखा करने का एक तरीका खोजने की कोशिश कर रहा हूं, अब तक, मुझे इंटरनेट में कुछ उपयोगी लेख मिला।

लेकिन मुझे अभी भी कुछ समस्या है। कृपया मेरे कोड की समीक्षा करें। मुझे अभी समझ नहीं आया कि कोड का क्या ServicePointManager.ServerCertificateValidationCallbackमतलब है।

इस प्रतिनिधि पद्धति को कब कहा जाएगा? और एक और सवाल, मुझे यह कोड किस जगह लिखना चाहिए? इससे पहले ServicePointManager.ServerCertificateValidationCallbackनिष्पादित या पहले Stream stream = request.GetRequestStream()?

public HttpWebRequest GetRequest()
{
    CookieContainer cookieContainer = new CookieContainer();

    // Create a request to the server
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(_remoteUrl);

    #region Set request parameters

    request.Method = _context.Request.HttpMethod;
    request.UserAgent = _context.Request.UserAgent;
    request.KeepAlive = true;
    request.CookieContainer = cookieContainer;
    request.PreAuthenticate = true;
    request.AllowAutoRedirect = false;

    #endregion

    // For POST, write the post data extracted from the incoming request
    if (request.Method == "POST")
    {
        Stream clientStream = _context.Request.InputStream;
        request.ContentType = _context.Request.ContentType;
        request.ContentLength = clientStream.Length;

        ServicePointManager.ServerCertificateValidationCallback = delegate(
            Object obj, X509Certificate certificate, X509Chain chain, 
            SslPolicyErrors errors)
            {
                return (true);
            };

            Stream stream = request.GetRequestStream();

            ....
        }

        ....

        return request;
    }
}   

जवाबों:


67

चूंकि केवल एक वैश्विक ServicePointManager है , जिससे ServicePointManager.ServerCertificateValidationCallback की स्थापना करने से परिणाम प्राप्त होगा कि बाद के सभी अनुरोध इस नीति को प्राप्त करेंगे। चूंकि यह एक वैश्विक "सेटिंग" है, इसलिए इसे Global.asax में Application_Start पद्धति में सेट करना पसंद किया जाएगा ।

कॉलबैक सेट करना डिफ़ॉल्ट व्यवहार को ओवरराइड करता है और आप स्वयं एक कस्टम सत्यापन रूटीन बना सकते हैं।


ऐसे ग्राहक के बारे में क्या जिसका कोई Global.asax नहीं है? मैं एक हैंडहेल्ड डिवाइस से स्थानीय नेटवर्क पर चलने वाली REST सेवा को कॉल कर रहा हूं।
बी क्ले शैनन

3
के लिए विशिष्ट है HttpWebRequest। यदि आप किसी अन्य साधन का उपयोग कर रहे हैं, तो आपको इसे पूरा करने के लिए प्रलेखन में देखना होगा।
सानी सिंह हट्टुएन

मैं WebRequest का उपयोग कर रहा हूं, जो HttpWebRequest पर जाती है, जैसे: ((HttpWebRequest) अनुरोध) .Accept = contentType;
बी क्ले शैनन

जैसा कि मेरे उत्तर में कहा गया है: इसे ग्लोबल में सेट करना PREFERRED है। कोई आवश्यकता नहीं है। आप इसे REST सेवा पर कॉल करने से पहले भी सेट कर सकते हैं।
शनि सिंह हट्टुनेन

3
संभावित समाधान के लिए इस लिंक को देखें ।
शनि सिंह हट्टुनेन

174

प्रति अनुरोध के आधार पर इस समाधान को लागू करने में रुचि रखने वाले किसी भी व्यक्ति के लिए, यह एक विकल्प है और एक लैम्ब्डा अभिव्यक्ति का उपयोग करता है। वही लैम्ब्डा अभिव्यक्ति को blak3r द्वारा उल्लिखित वैश्विक फ़िल्टर पर भी लागू किया जा सकता है। यह विधि .NET 4.5 की आवश्यकता प्रतीत होती है।

String url = "https://www.stackoverflow.com";
HttpWebRequest request = HttpWebRequest.CreateHttp(url);
request.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;

.NET 4.0 में, लैम्ब्डा एक्सप्रेशन को वैश्विक फ़िल्टर पर लागू किया जा सकता है

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

2
क्या FtpWebRequest के लिए कोई प्रति-अनुरोध समाधान है?
टिमो

यह मेरे 4.0
Nacht

मुझे लगता है कि अब तक 'वैश्विक' संस्करण के लिए एक अच्छा समाधान है, हालांकि मैं यह समझ सकता हूं कि आप इसे क्यों चाहते हैं। व्यक्तिगत रूप से मैं एक अनुरोध कारखाने का पक्ष लेता हूं जो तब इस सत्यापन कॉलबैक का प्रबंधन करता है। धन्यवाद एडम, अच्छा समाधान।
सीनेटर

2
रिटर्निंग trueकुछ जब विकास के दौरान प्रयोग आप कर सकते हैं, लेकिन यह असुरक्षित है। यह एक सशर्त होना चाहिए।
फ्रेड

1
उपयोग करना (HttpWebRequest)WebRequest.Create(url)पूरी तरह से मान्य है, लेकिन मेरे बॉक्स पर, HttpWebRequest.Create(url)अभी भी एक परियोजना लक्ष्यीकरण में मौजूद है। नेट 4.6.2। शेफ की पसंद, लेकिन इस बिंदु HttpClientपर उपयोग करने के लिए बेहतर एपीआई है।
एडम वेनेजिया

53

यह मेरे लिए काम किया:

System.Net.ServicePointManager.ServerCertificateValidationCallback +=
delegate(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate,
                        System.Security.Cryptography.X509Certificates.X509Chain chain,
                        System.Net.Security.SslPolicyErrors sslPolicyErrors)
    {
        return true; // **** Always accept
    };

यहाँ से स्निपेट करें: http://www.west-wind.com/weblog/posts/2011/Feb/11/HttpWebRequest-and-Ignoring-SSL-Certificate-Errors


17
ServicePointManager.ServerCertificateValidationCallback + = (प्रेषक, प्रमाणपत्र, श्रृंखला, sslPolicyErrors) => सत्य;
डेविड रुतगोस

3
हमेशा सच्चा लौटना असुरक्षित है। इसे सशर्त रूप से वापस लौटना चाहिए।
फ्रेड

यह प्रति-प्रक्रिया है, इसलिए यह सुरक्षित नहीं है।
मिखाइल ओरलोव

25

इसके अलावा संक्षिप्त प्रतिनिधि समाधान है:

ServicePointManager.ServerCertificateValidationCallback = delegate { return true; }; 

3
हमेशा वापसी trueअसुरक्षित है।
फ्रेड

7
हां, हमेशा सभी एसएसएल प्रमाणपत्रों पर भरोसा करना परिभाषा द्वारा असुरक्षित है। हो सके तो ऐसा करने से बचें।
लेडी रोमेल

@AndrejRommel अपने तरीके की सिफारिश की है?
किकेनेट

2
अनुशंसित तरीका एक वैध एसएसएल प्रमाणपत्र बनाना है और सर्वर पर नियंत्रण होने पर इसका ठीक से उपयोग करना है। हमने letencrypt.org का उपयोग करते हुए एक का निर्माण किया।
लेडी रोमेल

5

उल्लेख किया गया है कि .NET 4.5 से पहले इसे एक्सेस करने के अनुरोध पर संपत्ति ServicePointManagerउपलब्ध नहीं थी।

यहां .NET 4.0 कोड है जो आपको ServicePointप्रति-अनुरोध के आधार पर एक्सेस देगा । यह आपको प्रति-अनुरोध कॉलबैक तक पहुंच नहीं देता है, लेकिन इससे आपको समस्या के बारे में अधिक जानकारी मिल सकती है। बस scvPoint.Certificate(या ClientCertificateयदि आप चाहें) गुणों का उपयोग करें।

WebRequest request = WebRequest.Create(uri);

// oddity: these two .Address values are not necessarily the same!
//  The service point appears to be related to the .Host, not the Uri itself.
//  So, check the .Host vlaues before fussing in the debugger.
//
ServicePoint svcPoint = ServicePointManager.FindServicePoint(uri);
if (null != svcPoint)
{
    if (!request.RequestUri.Host.Equals(svcPoint.Address.Host, StringComparison.OrdinalIgnoreCase))
    {
        Debug.WriteLine(".Address              == " + request.RequestUri.ToString());
        Debug.WriteLine(".ServicePoint.Address == " + svcPoint.Address.ToString());
    }
    Debug.WriteLine(".IssuerName           == " + svcPoint.Certificate.GetIssuerName());
}

माना! लेकिन फिर, यह ओपी उनके बारे में ignoreहै, उन पर भरोसा नहीं।
जेसी चिशोल्म

वैसे भी, ServicePointमैं हमेशा सभी एसएसएल प्रमाणपत्रों पर भरोसा नहीं कर सकता , न ही सभी प्रमाणपत्रों को नजरअंदाज कर सकता हूं , क्योंकि ServerCertificateValidationCallback
सर्विसपीट

4

केवल संयोग से, यह किसी दिए गए ऐप में सभी प्रमाणपत्र सत्यापन को बंद करने का एक कम से कम क्रिया तरीका है जिसे मैं जानता हूं:

ServicePointManager.ServerCertificateValidationCallback = (a, b, c, d) => true;

4

ServicePointManager के लिए कॉलबैक जोड़ने के बजाय, जो विश्व स्तर पर प्रमाण पत्र सत्यापन को ओवरराइड करेगा, आप कॉलबैक को HttpClient के स्थानीय उदाहरण पर सेट कर सकते हैं। यह दृष्टिकोण केवल HttpClient के उस उदाहरण का उपयोग करके किए गए कॉल को प्रभावित करना चाहिए।

यहां नमूना कोड दिखाया जा रहा है कि वेब एपीआई नियंत्रक में विशिष्ट सर्वरों के लिए प्रमाणपत्र सत्यापन त्रुटियों की अनदेखी कैसे लागू की जा सकती है।

using System.Net.Http;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;

public class MyController : ApiController
{

    // use this HttpClient instance when making calls that need cert errors suppressed
    private static readonly HttpClient httpClient;

    static MyController()
    {
        // create a separate handler for use in this controller
        var handler = new HttpClientHandler();

        // add a custom certificate validation callback to the handler
        handler.ServerCertificateCustomValidationCallback = ((sender, cert, chain, errors) => ValidateCert(sender, cert, chain, errors));

        // create an HttpClient that will use the handler
        httpClient = new HttpClient(handler);
    }

    protected static ValidateCert(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors errors)
    {

        // set a list of servers for which cert validation errors will be ignored
        var overrideCerts = new string[]
        {
            "myproblemserver",
            "someotherserver",
            "localhost"
        };

        // if the server is in the override list, then ignore any validation errors
        var serverName = cert.Subject.ToLower();
        if (overrideCerts.Any(overrideName => serverName.Contains(overrideName))) return true;

        // otherwise use the standard validation results
        return errors == SslPolicyErrors.None;
    }

}

यह केवल .NET कोर के लिए काम नहीं करेगा? (या जब भी ServerCertificateCustomValidationCallback को HttpClientHandler में जोड़ा गया)?
फिलालिस्टिक

यह समाधान .Net फ्रेमवर्क 4.5 और बाद में .Net कोर में काम करना चाहिए (हालाँकि मैंने इसे .Net कोर में परीक्षण नहीं किया है)।
शेल्डन

@Sheldon, यह एक रत्न था :) सफलता के साथ एक .net और एक .net कोर ऐप के बीच मेरी लोकलहोस्ट एपी-कॉल्स में इस्तेमाल किया गया। सभी को स्वीकार किए बिना अच्छा समाधान।
बड़ी

3

एडम के जवाब और रोब की टिप्पणी के आधार पर मैंने इसका इस्तेमाल किया:

ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => certificate.Issuer == "CN=localhost";

जो कुछ हद तक "अनदेखी" को फ़िल्टर करता है। अन्य जारीकर्ताओं को पाठ्यक्रम में आवश्यकतानुसार जोड़ा जा सकता है। यह .NET 2.0 में परीक्षण किया गया था क्योंकि हमें कुछ विरासत कोड का समर्थन करने की आवश्यकता है।


@Kank देर से जवाब के लिए क्षमा करें - इसे वास्तविक कॉल से पहले कहीं भी जोड़ा जा सकता है, जैसे। कॉल करने से पहले request.GetResponse ()। ध्यान दें कि जारीकर्ता में आपके मामले में कुछ और हो सकता है।
लेडी ग्रोबलर

3

CA5386: भेद्यता विश्लेषण उपकरण आपको इन कोडों के लिए सचेत करेंगे।

सही कोड:

ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) =>
{
   return (sslPolicyErrors & SslPolicyErrors.RemoteCertificateNotAvailable) != SslPolicyErrors.RemoteCertificateNotAvailable;
};

3

.Net कोर के लिए

using (var handler = new HttpClientHandler())
{ 
    // allow the bad certificate
    handler.ServerCertificateCustomValidationCallback = (request, cert, chain, errors) => true;
    using (var httpClient = new HttpClient(handler))
    {
        await httpClient.PostAsync("the_url", null);
    }
}

2

स्पष्ट रूप से व्यक्त ...

ServicePointManager.ServerCertificateValidationCallback += new System.Net.Security.RemoteCertificateValidationCallback(CertCheck);

private static bool CertCheck(object sender, X509Certificate cert,
X509Chain chain, System.Net.Security.SslPolicyErrors error)
{
    return true;
}

0

Sani's और blak3r के उत्तरों को जोड़ते हुए, मैंने अपने एप्लिकेशन के लिए स्टार्टअप कोड में निम्नलिखित जोड़ा है, लेकिन VB में:

'** Overriding the certificate validation check.
Net.ServicePointManager.ServerCertificateValidationCallback = Function(sender, certificate, chain, sslPolicyErrors) True

चालबाजी करने लगता है।


0

युक्ति: आप इस पद्धति का उपयोग उन प्रमाणपत्रों को ट्रैक करने के लिए भी कर सकते हैं जो जल्द ही समाप्त होने वाले हैं। यह आपके बेकन को बचा सकता है यदि आप एक प्रमाण पत्र की खोज करते हैं जो समाप्त होने वाला है और इसे समय में ठीक किया जा सकता है। तीसरे पक्ष की कंपनियों के लिए भी अच्छा है - हमारे लिए यह डीएचएल / फेडेक्स है। डीएचएल ने सिर्फ एक सर्टिफिकेट एक्सपायर होने दिया, जो थैंक्सगिविंग से 3 दिन पहले हमें खराब कर रहा है। सौभाग्य से मैं इसे ठीक करने के लिए ... इस बार!

    private static DateTime? _nextCertWarning;
    private static bool ValidateRemoteCertificate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors error)
    {
        if (error == SslPolicyErrors.None)
        {
            var cert2 = cert as X509Certificate2;
            if (cert2 != null)
            { 
                // If cert expires within 2 days send an alert every 2 hours
                if (cert2.NotAfter.AddDays(-2) < DateTime.Now)
                {
                    if (_nextCertWarning == null || _nextCertWarning < DateTime.Now)
                    {
                        _nextCertWarning = DateTime.Now.AddHours(2);

                        ProwlUtil.StepReached("CERT EXPIRING WITHIN 2 DAYS " + cert, cert.GetCertHashString());   // this is my own function
                    }
                }
            }

            return true;
        }
        else
        {
            switch (cert.GetCertHashString())
            {
                // Machine certs - SELF SIGNED
                case "066CF9CAD814DE2097D367F22D3A7E398B87C4D6":    

                    return true;

                default:
                    ProwlUtil.StepReached("UNTRUSTED CERT " + cert, cert.GetCertHashString());
                    return false;
            }
        }
    }

उस स्थिति को संभालना सुनिश्चित करें जहां आपके अलर्टिंग तंत्र की समय सीमा समाप्त हो सकती है - या आप स्टैकओवरफ़्लो के साथ समाप्त होंगे!
साइमन_वेर

क्या है ProwlUtil.StepReached?

क्षमा करें कि प्रॉल एपीआई को कॉल करने का मेरा अपना तरीका है जो मेरे फोन पर सूचनाएं भेज सकता है। हालाँकि आप लॉग इन करना चाहते हैं यह अच्छा है। मुझे इस तरह की चीजों के लिए अपने फोन पर बग होना पसंद है!
साइमन_वेर

0

काम के ऊपर कई जवाब। मैं एक दृष्टिकोण चाहता था कि मुझे कोड में बदलाव करने की ज़रूरत नहीं है और मैंने अपने कोड को असुरक्षित नहीं बनाया है। इसलिए मैंने एक श्वेतसूची बनाई। श्वेतसूची को किसी भी डेटास्टर में बनाए रखा जा सकता है। मैंने config फाइल का उपयोग किया है क्योंकि यह एक बहुत छोटी सूची है।

मेरा कोड नीचे है।

ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, error) => {
    return error == System.Net.Security.SslPolicyErrors.None || certificateWhitelist.Contains(cert.GetCertHashString());
};

0

इस समाधान का एकता C # संस्करण:

void Awake()
{
    System.Net.ServicePointManager.ServerCertificateValidationCallback += ValidateCertification;
}

void OnDestroy()
{
    ServerCertificateValidationCallback = null;
}

public static bool ValidateCertification(object sender, X509Certificate certificate, X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors)
{
    return true;
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.