.net कोर में अमान्य SSL प्रमाणपत्र को बायपास करें


103

मैं एक ऐसी परियोजना पर काम कर रहा हूं, जिसे किसी https साइट से कनेक्ट करने की आवश्यकता है। हर बार जब मैं कनेक्ट करता हूं, तो मेरा कोड अपवाद फेंकता है क्योंकि उस साइट का प्रमाणपत्र अविश्वसनीय साइट से आता है। क्या .net कोर http में सर्टिफिकेट चेक बायपास करने का कोई तरीका है?

मैंने इस कोड को .NET के पिछले संस्करण से देखा था। मुझे लगता है कि मुझे बस कुछ ऐसा चाहिए।

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

जवाबों:


28

ServicePointManager.ServerCertkutValidationCallback .Net कोर में समर्थित नहीं है।

वर्तमान स्थिति यह है कि यह आगामी 4.1 के लिए एक नया ServerCertificateCustomValidationCallback विधि होगी । * System.Net.Http अनुबंध (HttpClient)। .NET कोर टीम अब 4.1 अनुबंध को अंतिम रूप दे रही है। आप इसके बारे में यहाँ जीथब पर पढ़ सकते हैं

आप Core.x में सीधे स्रोतों का उपयोग करके या MYGET फ़ीड पर सीधे System.Net.Http 4.1 के पूर्व-रिलीज़ संस्करण को आज़मा सकते हैं: https://dotnet.myget.org/gallery/dotnet-core

Github पर वर्तमान WinHttpHandler.ServerCertificateCustomValidationCallback परिभाषा


8
यह केवल विंडोज पर काम करता है। क्या आपके पास लिनक्स के लिए एक समाधान है? धन्यवाद।
व्लादिमीर

145

अपडेट करें:

जैसा कि नीचे उल्लेख किया गया है, सभी कार्यान्वयन इस कॉलबैक (यानी आईओएस जैसे प्लेटफॉर्म) का समर्थन नहीं करते हैं। इस मामले में, जैसा कि डॉक्स कहते हैं, आप सत्यापनकर्ता को स्पष्ट रूप से सेट कर सकते हैं:

handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;

यह .NET कोर 2.2, 3.0 और 3.1 के लिए भी काम करता है

अधिक नियंत्रण के साथ पुराना उत्तर , लेकिन फेंक सकता है PlatformNotSupportedException:

आप एक गुमनाम कॉलबैक फ़ंक्शन जैसे HTTP कॉल पर एसएसएल सर्टिफिकेट चेक को ओवरराइड कर सकते हैं

using (var httpClientHandler = new HttpClientHandler())
{
   httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => { return true; };
   using (var client = new HttpClient(httpClientHandler))
   {
       // Make your request...
   }
}

इसके अतिरिक्त, मैं एक फैक्ट्री पैटर्न का उपयोग करने का सुझाव देता हूं HttpClientक्योंकि यह एक साझा वस्तु है जिसे तुरंत निपटाया नहीं जा सकता है और इसलिए कनेक्शन खुले रहेंगे


3
मैं .Net Core 1.0 का उपयोग कर रहा हूं और यह मेरे लिए काम कर रहा है। एक हेड के रूप में ऐसा लगता है। नेट कोर 2.0 ने एक HttpClientसंपत्ति जोड़ी है, DangerousAcceptAnyServerCertificateValidatorजो मैकओएसएक्स पर इस काम को बनाने का एक तरीका प्रदान करती है। यहाँ अधिक जानकारी - github.com/dotnet/corefx/pull/19908
Troy Witthoeft

1
एडब्ल्यूएस लैम्ब्डा के साथ इसका उपयोग करते हुए, .NET कोर 1.0 ने सही किया कि मुझे कस्टम रूट CA सर्टिफिकेट के साथ आंतरिक HTTPS से कनेक्ट करने से रोक रहा था।
क्विकनाउल

किसी के factory patternलिए HttpClient?
किनिकेट

@Kiquenet बस एक फैक्ट्री बनाएं, जहां GetHttpClientविधि कॉन्फ़िगर को लौटाए HttpClientऔर इसे एक using-ब्लॉक के भीतर उपयोग करें ।
लकी लाइक

यह स्वीकृत उत्तर होना चाहिए, खासकर जब से यह एक एकल ग्राहक उपयोग के लिए स्कोप किया जा सकता है।
बाइनरीपैट्रिक

36

मैं इस के साथ हल:

Startup.cs

public void ConfigureServices(IServiceCollection services)
    {
        services.AddHttpClient("HttpClientWithSSLUntrusted").ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler
        {
            ClientCertificateOptions = ClientCertificateOption.Manual,
            ServerCertificateCustomValidationCallback =
            (httpRequestMessage, cert, cetChain, policyErrors) =>
            {
                return true;
            }
        });

YourService.cs

public UserService(IHttpClientFactory clientFactory, IOptions<AppSettings> appSettings)
    {
        _appSettings = appSettings.Value;
        _clientFactory = clientFactory;
    }

var request = new HttpRequestMessage(...

var client = _clientFactory.CreateClient("HttpClientWithSSLUntrusted");

HttpResponseMessage response = await client.SendAsync(request);

32

उसी समस्या के जवाब की तलाश में यहां आया था, लेकिन मैं नेट कोर के लिए डब्ल्यूसीएफ का उपयोग कर रहा हूं। यदि आप एक ही नाव में हैं, तो उपयोग करें:

client.ClientCredentials.ServiceCertificate.SslCertificateAuthentication = 
    new X509ServiceCertificateAuthentication()
    {
        CertificateValidationMode = X509CertificateValidationMode.None,
        RevocationMode = X509RevocationMode.NoCheck
    };

सभी प्रमाणपत्रों और AppDomain के लिए वैश्विक?
किकेनेट

@Kiquenet: मुझे विश्वास है, हाँ। कहीं और एक अद्यतन जवाब के लिए जाँच करें, अब एक बेहतर समाधान हो सकता है। एक साल हो गया है। मुझे लगता है कि अगर आप और कुछ नहीं करते तो आप प्रमाणक को अपने अधीन कर सकते हैं। और नहीं, HttpClient के लिए कोई देशी कारखाना नहीं है जिसे मैं जानता हूं। यदि आपको अधिक कार्यक्षमता की आवश्यकता है, तो RestClient को देखें।
लार्सन

HttpClient (.NET Core 3.1) में कोई ClientCredentials गुण नहीं है।
Павле

@ Павле: मैंने इस परियोजना को अभी तक 3.1 में अपडेट नहीं किया है, लेकिन इस तरह की संपत्ति होनी चाहिए: डॉक्स.कमीसिटी . com / en-us / dotnet / api/…
ट्रॉल्स लार्सन

@ Павле: यह उत्तर HttpClient के बारे में नहीं है, बल्कि WCF सेवा द्वारा उत्पन्न ग्राहक है। मेरे ASMX SoapClient के लिए भी काम किया, बहुत धन्यवाद!
Jan Zahradník

14

.NetCore में, आप निम्न कोड स्निपेट को सेवाओं को कॉन्फ़िगर करने की विधि में जोड़ सकते हैं, मैंने यह सुनिश्चित करने के लिए एक चेक जोड़ा कि हम केवल विकास के माहौल में एसएसएल प्रमाणपत्र पास करके

services.AddHttpClient("HttpClientName", client => {
// code to configure headers etc..
}).ConfigurePrimaryHttpMessageHandler(() => {
                  var handler = new HttpClientHandler();
                  if (hostingEnvironment.IsDevelopment())
                  {
                      handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => { return true; };
                  }
                  return handler;
              });

1
क्यों -ve, यह बिल्कुल वही लागू कर रहा है जो दूसरों ने mvc.net कोड में सुझाया है और उन्होंने इस पर अंक बनाए हैं, मैं सिर्फ .netCore कोड
Sameh

शायद। क्योंकि यह किसी भी स्पष्टीकरण का अभाव है। इस दृष्टिकोण को किसी अन्य पर क्यों लिया जाना चाहिए, कॉलिंग सेक्शन में क्या कोड लिखा जाना चाहिए (जैसे mycontroller.cs), जो स्पष्टीकरण का हिस्सा हो सकता है। कोई भी आधिकारिक दस्तावेज / उद्धरण।
भानु छाबड़ा

जैसा कि मैंने कहा कि यदि आपने थ्रेड के शीर्ष पर अन्य टिप्पणियों की समीक्षा की है तो बहुत अंतर नहीं है और फिर भी उन्होंने 18 और 81 अंक बनाए हैं,
वही

1
क्योंकि उन्होंने अपने उत्तरों का समर्थन करते हुए पाठ जोड़ा है, कृपया दिशानिर्देशों को एक बार फिर से पढ़ें। आपकी मदद कर सकता है, @moderators सटीक समस्याओं को इंगित कर सकते हैं IMHO।
भानु छाबड़ा

8

.NET कोर 2.2 और डॉक लाइनर कंटेनरों पर स्व-हस्ताक्षरित सीट्स और क्लाइंट सर्टिफिकेट के साथ काम करते समय मुझे उसी समस्या का सामना करना पड़ा। मेरे देव विंडोज मशीन पर सब कुछ ठीक रहा, लेकिन डॉकटर में मुझे ऐसी त्रुटि मिली:

System.Security.Authentication.AuthenticationException: सत्यापन प्रक्रिया के अनुसार दूरस्थ प्रमाणपत्र अमान्य है

सौभाग्य से, प्रमाण पत्र एक श्रृंखला का उपयोग करके उत्पन्न किया गया था। बेशक, आप हमेशा इस समाधान को अनदेखा कर सकते हैं और उपरोक्त समाधानों का उपयोग कर सकते हैं।

तो यहाँ मेरा समाधान है:

  1. मैंने P7B प्रारूप में अपने कंप्यूटर पर Chrome का उपयोग करके प्रमाणपत्र सहेजा है ।

  2. इस आदेश का उपयोग करके PEM प्रारूप में प्रमाणपत्र बदलें:
    openssl pkcs7 -inform DER -outform PEM -in <cert>.p7b -print_certs > ca_bundle.crt

  3. Ca_bundle.crt फ़ाइल खोलें और एक साफ़ फ़ाइल छोड़कर सभी विषय रिकॉर्डिंग हटाएं। नीचे उदाहरण:

    -----BEGIN CERTIFICATE-----
    _BASE64 DATA_
    -----END CERTIFICATE-----
    -----BEGIN CERTIFICATE-----
    _BASE64 DATA_
    -----END CERTIFICATE-----
    -----BEGIN CERTIFICATE-----
    _BASE64 DATA_
    -----END CERTIFICATE-----
  1. इन पंक्तियों को Dockerfile में रखें (अंतिम चरणों में):
    # Update system and install curl and ca-certificates
    RUN apt-get update && apt-get install -y curl && apt-get install -y ca-certificates
    # Copy your bundle file to the system trusted storage
    COPY ./ca_bundle.crt /usr/local/share/ca-certificates/ca_bundle.crt
    # During docker build, after this line you will get such output: 1 added, 0 removed; done.
    RUN update-ca-certificates
  1. एप्लिकेशन में:
    var address = new EndpointAddress("https://serviceUrl");                
    var binding = new BasicHttpsBinding
    {
        CloseTimeout = new TimeSpan(0, 1, 0),
        OpenTimeout = new TimeSpan(0, 1, 0),
        ReceiveTimeout = new TimeSpan(0, 1, 0),
        SendTimeout = new TimeSpan(0, 1, 0),
        MaxBufferPoolSize = 524288,
        MaxBufferSize = 65536,
        MaxReceivedMessageSize = 65536,
        TextEncoding = Encoding.UTF8,
        TransferMode = TransferMode.Buffered,
        UseDefaultWebProxy = true,
        AllowCookies = false,
        BypassProxyOnLocal = false,
        ReaderQuotas = XmlDictionaryReaderQuotas.Max,
        Security =
        {
            Mode = BasicHttpsSecurityMode.Transport,
            Transport = new HttpTransportSecurity
            {
                ClientCredentialType = HttpClientCredentialType.Certificate,
                ProxyCredentialType = HttpProxyCredentialType.None
            }
        }
    };
    var client = new MyWSClient(binding, address);
    client.ClientCredentials.ClientCertificate.Certificate = GetClientCertificate("clientCert.pfx", "passwordForClientCert");
    // Client certs must be installed
    client.ClientCredentials.ServiceCertificate.SslCertificateAuthentication = new X509ServiceCertificateAuthentication
    {
        CertificateValidationMode = X509CertificateValidationMode.ChainTrust,
        TrustedStoreLocation = StoreLocation.LocalMachine,
        RevocationMode = X509RevocationMode.NoCheck
    };

GetClientCertificate विधि:

private static X509Certificate2 GetClientCertificate(string clientCertName, string password)
{
    //Create X509Certificate2 object from .pfx file
    byte[] rawData = null;
    using (var f = new FileStream(Path.Combine(AppContext.BaseDirectory, clientCertName), FileMode.Open, FileAccess.Read))
    {
        var size = (int)f.Length;
        var rawData = new byte[size];
        f.Read(rawData, 0, size);
        f.Close();
    }
    return new X509Certificate2(rawData, password);
}

4

सबसे पहले, यह उत्पादन में उपयोग नहीं करते

यदि आप AddHttpClient मिडलवेयर का उपयोग कर रहे हैं तो यह उपयोगी होगा। मुझे लगता है कि विकास के उद्देश्य की जरूरत है न कि उत्पादन की। जब तक आप एक वैध प्रमाण पत्र नहीं बनाते हैं, तब तक आप इस फंक का उपयोग कर सकते हैं।

Func<HttpMessageHandler> configureHandler = () =>
        {
            var bypassCertValidation = Configuration.GetValue<bool>("BypassRemoteCertificateValidation");
            var handler = new HttpClientHandler();
            //!DO NOT DO IT IN PRODUCTION!! GO AND CREATE VALID CERTIFICATE!
            if (bypassCertValidation)
            {
                handler.ServerCertificateCustomValidationCallback = (httpRequestMessage, x509Certificate2, x509Chain, sslPolicyErrors) =>
                {
                    return true;
                };
            }
            return handler;
        };

और इसे लागू करें

services.AddHttpClient<IMyClient, MyClient>(x => { x.BaseAddress = new Uri("https://localhost:5005"); })
        .ConfigurePrimaryHttpMessageHandler(configureHandler);

3

सभी प्रमाणपत्रों की अनुमति देना बहुत शक्तिशाली है लेकिन यह खतरनाक भी हो सकता है। यदि आप केवल वैध प्रमाण पत्र और कुछ निश्चित प्रमाण पत्र देना चाहते हैं तो यह इस तरह से किया जा सकता है।

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

मूल स्रोत:

https://stackoverflow.com/a/44140506/3850405

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.