অবিশ্বাস্য এসএসএল শংসাপত্রগুলিকে এইচটিটিপিপ্লায়েন্টের সাহায্যে অনুমতি দেওয়া হচ্ছে


114

আমি এসএসএলের মাধ্যমে আমার পরীক্ষার ওয়েব এপিআইয়ের সাথে যোগাযোগ করার জন্য আমার উইন্ডোজ 8 অ্যাপ্লিকেশনটি পেতে লড়াই করছি।

দেখে মনে হয় যে HTRClient / HttpClientHandler WebRequest এর মতো অবিশ্বস্ত শংসাপত্রগুলি উপেক্ষা করার বিকল্প সরবরাহ করে না এবং বিকল্প দেয় না (তবে এটি একটি "হ্যাকি" উপায়ে হলেও ServerCertificateValidationCallback) সক্ষম করে।

কোন সাহায্যের অনেক প্রশংসা হবে!


5
যদি আপনি .NET কোর ব্যবহার করছেন আপনি আগ্রহী হতে পারে এই উত্তর।
kdaveid

উত্তর:


13

উইন্ডোজ 8.1 এর সাহায্যে আপনি এখন অবৈধ এসএসএল শংসাপত্রগুলিতে বিশ্বাস করতে পারেন। আপনাকে উইন্ডোজ.ওয়েব.হট্টপ্লেইয়েন্ট ব্যবহার করতে হবে অথবা আপনি যদি সিস্টেম.নেট.এইচটিপি.এইচটিপি ক্লিনেন্ট ব্যবহার করতে চান তবে আপনি লিখেছেন বার্তা হ্যান্ডলার অ্যাডাপ্টারটি ব্যবহার করতে পারেন: http://www.nuget.org/packages/WinRtHttpClientHandler

দস্তাবেজগুলি গিটহাবটিতে রয়েছে: https://github.com/onovotny/WinRtHttpClientHandler


12
আপনার সমস্ত কোড ব্যবহার না করে এটি করার কোনও উপায় আছে? অন্য কথায়, আপনার সমাধানের সারাংশ কি?
ওয়েনসভিন

সমাধানটির সূচনাটি হ'ল উইন্ডোজ এইচটিপি ক্লায়েন্ট হ্যান্ডলারের মোড়ক এবং এটি HTTPClient বাস্তবায়ন হিসাবে ব্যবহার করা। এটি সমস্ত এই ফাইলে রয়েছে: github.com/onovotny/WinRtHttpClientHandler/blob/master/… এটিকে অনুলিপি করতে অনিচ্ছুক তবে কেন কেবল প্যাকেজটি ব্যবহার করবেন না তা নিশ্চিত নন।
ক্লেয়ার নভোটনি

@ ওরেএনভোটনি তাই আপনার সমাধানটি উইন্ডোজ সংস্করণে আবদ্ধ নয়?
চেস্টার 89

আমি এটি আমার ইউডাব্লুপি অ্যাপ্লিকেশনটিতে প্রয়োগ করেছি এবং আমি নীচের ফিল্টারগুলির উদাহরণ ব্যবহার করেছি। আমি এখনও একই ত্রুটি পেয়েছি।
খ্রিস্টান ফান্ডলে 20'18

158

একটি দ্রুত এবং নোংরা সমাধান হ'ল ServicePointManager.ServerCertificateValidationCallbackপ্রতিনিধি ব্যবহার করা । এটি আপনাকে নিজের শংসাপত্রের বৈধতা সরবরাহ করতে দেয়। বৈধতা পুরো অ্যাপ্লিকেশন ডোমেন জুড়ে বিশ্বব্যাপী প্রয়োগ করা হয়।

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

আমি এটি প্রধানত এমন পরিস্থিতিতে ইউনিট পরীক্ষার জন্য ব্যবহার করি যেখানে আমি যে প্রান্তে হোস্টিং করছি এমন কোনও শেষ পয়েন্টের বিরুদ্ধে চালাতে চাই এবং এটি ডাব্লুসিএফ ক্লায়েন্ট বা এর সাথে আঘাত করার চেষ্টা করছি HttpClient

প্রোডাকশন কোডের জন্য আপনি আরও সূক্ষ্ম দানাদার নিয়ন্ত্রণ পেতে চাইতে পারেন WebRequestHandlerএবং এর ServerCertificateValidationCallbackপ্রতিনিধি সম্পত্তি ( ডিটিবির উত্তর নীচে দেখুন ) ব্যবহার করা ভাল । অথবা ctacke উত্তর ব্যবহার করে HttpClientHandler। আমি এখনই এই দুটিয়ের মধ্যে দুটিকেই পছন্দ করছি এমনকি আমার ইন্টিগ্রেশন টেস্টের সাথেও আমি কীভাবে এটি ব্যবহার করতাম যদি না আমি অন্য কোনও হুক না পাই।


32
ডাউনভোটার নয়, সার্ভারের্টিফিকেটভিডেশন ক্যালব্যাকের সবচেয়ে বড় সমস্যা হ'ল এটি মূলত আপনার অ্যাপডোমাইনের কাছে বৈশ্বিক। সুতরাং আপনি যদি এমন একটি লাইব্রেরি লিখছেন যা কোনও অবিশ্বস্ত শংসাপত্রের সাথে কোনও সাইটে কল করতে এবং এই কাজটি নিয়োগের প্রয়োজন হয়, আপনি কেবল আপনার লাইব্রেরি নয়, পুরো অ্যাপ্লিকেশনটির আচরণ পরিবর্তন করছেন। এছাড়াও, লোকেরা সবসময় 'অন্ধভাবে ফিরে আসবে' পদ্ধতির সাথে সতর্ক হওয়া উচিত। এটিতে গুরুতর সুরক্ষা জড়িত। এটি সরবরাহিত প্যারামিটারগুলি পড়া / * পরীক্ষা করা উচিত এবং তারপরে সাবধানে সিদ্ধান্ত নেওয়া উচিত * / / সত্যে ফিরে আসবেন কি না;
scottt732

@ স্কটট 732 অবশ্যই একটি বৈধ পয়েন্ট এবং উল্লেখযোগ্য তবে এটি এখনও একটি বৈধ সমাধান। সম্ভবত ওপি কর্তৃক আসল প্রশ্নটি পড়ার পরে মনে হয় তিনি সার্ভারসर्টিটিভালিডেশন ক্যালব্যাক হ্যান্ডলার সম্পর্কে ইতিমধ্যে ওয়াকিবহাল ছিলেন
ব্রোনমস্কি

2
আমি অন্তত প্রেরকের মতো কিছু মানদণ্ডে ফিল্টার করার পরামর্শ দেব
বোস এনকলার

2
আমাকে সত্যিই ওয়েব রেকুয়েস্টহ্যান্ডলার বিকল্প বনাম গ্লোবাল সার্ভিসপয়েন্ট ম্যানেজারের পরামর্শ দিতে হবে।
থমাস এস ট্রায়াস

3
আপনাকে বিশ্বব্যাপী সার্ভিসপয়েন্ট ম্যানেজার ব্যবহার করতে হবে না, আপনি পরিষেবা পয়েন্টটি পেতে ServicePointManager.GetServicePoint(Uri) ( ডক্স দেখুন ) ব্যবহার করতে পারেন যা কেবলমাত্র সেই ইউআরআই-তে কলগুলির ক্ষেত্রে প্রযোজ্য। তারপরে আপনি সেই উপসেটের উপর ভিত্তি করে বৈশিষ্ট্যগুলি সেট করতে এবং ইভেন্টগুলি পরিচালনা করতে পারেন।
ওটসোদা

87

কটাক্ষপাত আছে WebRequestHandler ক্লাস এবং তার ServerCertificateValidationCallback প্রপার্টি :

using (var handler = new WebRequestHandler())
{
    handler.ServerCertificateValidationCallback = ...

    using (var client = new HttpClient(handler))
    {
        ...
    }
}

5
আমি ইতিমধ্যে যে প্রতিক্রিয়াটি দেখেছি তার জন্য ধন্যবাদ - এটি উইন্ডোজ 8 স্টোর অ্যাপ্লিকেশনগুলির জন্য। নেট মধ্যে উপস্থিত নেই।
জেমি

তবে, নিজের নিজস্ব HTTPClientHandler বা HTTPMessageHandler উত্পন্ন ক্লাস তৈরি করা যথেষ্ট সহজ, বিশেষত সত্য যে WebRequestHandler উত্স সহজেই উপলব্ধ।
থমাস এস ট্রায়াস

@ থমাস এস। ট্রাইস সম্পর্কে কোন নমুনা? derived class?
কুইকিনেট

2
ব্যবহার করছেন HttpClientHandler?
কুইকিনেট

1
@ কিকিনেট এই উত্তরটি ২০১২ সালের, এটি ইতিমধ্যে years বছর বয়সী, এবং হ্যাঁ - এই সময়ে অনেক লোক নিশ্চিত ছিল যে এটি httpclient ব্যবহারের সঠিক উপায় :)
জাস্টমারা

63

আপনি যদি নেট। স্ট্যান্ডার্ড লাইব্রেরিতে এটি করার চেষ্টা করছেন, কেবলমাত্র trueআপনার হ্যান্ডলারে ফিরে আসার সমস্ত ঝুঁকি সহ এখানে একটি সহজ সমাধান । আমি আপনার উপর নিরাপত্তা ছেড়ে।

var handler = new HttpClientHandler();
handler.ClientCertificateOptions = ClientCertificateOption.Manual;
handler.ServerCertificateCustomValidationCallback = 
    (httpRequestMessage, cert, cetChain, policyErrors) =>
{
    return true;
};

var client = new HttpClient(handler);

1
প্ল্যাটফর্মের এই ফলাফলগুলি uwp থেকে রেফারেন্সের সময় সমর্থন করা যায় না
ইভান

ইউডব্লিউপিতে আমার পক্ষে কাজ করেছেন। সম্ভবত সমর্থন কভারেজ 14 মাসে পরিণত হয়েছে। দ্রষ্টব্য: এই হ্যাকটি কেবল পরীক্ষার / ডিএনভি এনভির জন্য প্রয়োজনীয় (যেখানে স্ব-স্বাক্ষরিত শংসাপত্রগুলি ব্যবহৃত হচ্ছে)
বেন ম্যাকিন্টায়ার

আমি এই কোডটি চালিয়েছি এবং সর্বদা System.NotImplementedException এর সাথে দেখা করি। কেন জানি না।
লিউ ফেং

25

অথবা তোমার জন্য ব্যবহার করতে পারেন HttpClient মধ্যে Windows.Web.Httpনামস্থান:

var filter = new HttpBaseProtocolFilter();
#if DEBUG
    filter.IgnorableServerCertificateErrors.Add(ChainValidationResult.Expired);
    filter.IgnorableServerCertificateErrors.Add(ChainValidationResult.Untrusted);
    filter.IgnorableServerCertificateErrors.Add(ChainValidationResult.InvalidName);
#endif
using (var httpClient = new HttpClient(filter)) {
    ...
}

আমি ব্যবহার করতে পারি System.Net.Http, System.Webএবং Windows.Web.Httpএকসঙ্গে?
কুইকিনেট

2
HTTPClient .NET স্ট্যান্ডার্ড বা UWP এ ওভাররাইড আছে বলে মনে হয় না।
খ্রিস্টান ফান্ডলে 20'18

"ব্যবহার" প্যাটার্নটি ব্যবহার করবেন না: ডকস.মাইক্রোসফটকম
বার্নহার্ড

15

আপনি যদি ব্যবহার করেন তবে System.Net.Http.HttpClientআমি বিশ্বাস করি সঠিক প্যাটার্নটি is

var handler = new HttpClientHandler() 
{ 
    ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
};

var http = new HttpClient(handler);
var res = http.GetAsync(url);

8

এখানে বেশিরভাগ উত্তরগুলি আদর্শ প্যাটার্নটি ব্যবহার করার পরামর্শ দেয়:

using (var httpClient = new HttpClient())
{
 // do something
}

কারণ আইডিস্পোজেবল ইন্টারফেস। দয়া করে না!

মাইক্রোসফ্ট আপনাকে বলে যে:

এবং এখানে আপনি পর্দার আড়ালে কী চলছে তার বিশদ বিশ্লেষণ খুঁজে পেতে পারেন: https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/

আপনার এসএসএল প্রশ্ন সম্পর্কিত এবং https://docs.microsoft.com/en-us/azure/architecture/antipatterns/improper-instantiation/#how-to-fix-the-problem এর উপর ভিত্তি করে

আপনার প্যাটার্নটি এখানে:

class HttpInterface
{
 // https://docs.microsoft.com/en-us/azure/architecture/antipatterns/improper-instantiation/#how-to-fix-the-problem
 // https://docs.microsoft.com/en-us/dotnet/api/system.net.http.httpclient#remarks
 private static readonly HttpClient client;

 // static initialize
 static HttpInterface()
 {
  // choose one of these depending on your framework

  // HttpClientHandler is an HttpMessageHandler with a common set of properties
  var handler = new HttpClientHandler();
  {
      ServerCertificateCustomValidationCallback = delegate { return true; },
  };
  // derives from HttpClientHandler but adds properties that generally only are available on full .NET
  var handler = new WebRequestHandler()
  {
      ServerCertificateValidationCallback = delegate { return true; },
      ServerCertificateCustomValidationCallback = delegate { return true; },
  };

  client = new HttpClient(handler);
 }

 .....

 // in your code use the static client to do your stuff
 var jsonEncoded = new StringContent(someJsonString, Encoding.UTF8, "application/json");

 // here in sync
 using (HttpResponseMessage resultMsg = client.PostAsync(someRequestUrl, jsonEncoded).Result)
 {
  using (HttpContent respContent = resultMsg.Content)
  {
   return respContent.ReadAsStringAsync().Result;
  }
 }
}

প্রশ্ন স্ব স্বাক্ষরিত সার্টের বিশ্বাসের সম্পর্কের জন্য। আপনার সম্পূর্ণ উত্তরটি (এমনকি এটির বৈধ হিসাবে বিবেচিত) এইচটিপিপিপ্লায়েন্ট থ্রেডকে সুরক্ষিত করার বিষয়ে।
আদর্শ

1
এটি কেবল "থ্রেড সুরক্ষা" সম্পর্কে নয়। আমি "অক্ষম" এসএসএল যাচাইকরণ সহ httpclient ব্যবহারের "সঠিক" উপায়টি দেখাতে চেয়েছিলাম। অন্যান্য উত্তর "বিশ্বব্যাপী" শংসাপত্র পরিচালককে পরিবর্তন করে mod
বার্নহার্ড

7

এটি যদি কোনও উইন্ডোজ রানটাইম অ্যাপ্লিকেশনটির জন্য হয় তবে আপনাকে প্রকল্পে স্ব-স্বাক্ষরিত শংসাপত্র যুক্ত করতে হবে এবং অ্যাপ্লিকেশনটিতে এটি উল্লেখ করতে হবে।

দস্তাবেজগুলি এখানে রয়েছে: http://msdn.microsoft.com/en-us/library/windows/apps/hh465031.aspx

একই জিনিস যদি এটি বিশ্বাসযোগ্য নয় এমন একটি সিএ থেকে আসে (যেমন কোনও ব্যক্তিগত সিএ যেমন মেশিন নিজেই বিশ্বাস করে না) - আপনাকে সিএর পাবলিক সার্টিফিকেট পেতে হবে, অ্যাপ্লিকেশনটিতে বিষয়বস্তু হিসাবে এটি যুক্ত করতে হবে এবং পরে তা ম্যানিফেস্টে যুক্ত করতে হবে।

এটি শেষ হয়ে গেলে অ্যাপটি এটিকে সঠিকভাবে স্বাক্ষরিত শংসাপত্র হিসাবে দেখবে।


2

আমার কাছে উত্তর নেই তবে আমার কাছে বিকল্প আছে।

আপনি ট্রাফিক নিরীক্ষণ করতে এবং এইচডিটিপিএস ডিক্রিপশন সক্ষম করতে যদি ফিডলার 2 ব্যবহার করেন তবে আপনার বিকাশের পরিবেশটি অভিযোগ করবে না। এটি উইনআরটি ডিভাইসগুলিতে যেমন কাজ করবে না যেমন মাইক্রোসফ্ট সারফেস, কারণ আপনি সেগুলিতে স্ট্যান্ডার্ড অ্যাপ্লিকেশন ইনস্টল করতে পারবেন না। তবে আপনার ডেভলপমেন্ট উইন 8 কম্পিউটার ঠিক থাকবে।

Fiddler2 এ HTTPS এনক্রিপশন সক্ষম করতে, সরঞ্জামসমূহ> ফিডলার বিকল্পসমূহ> HTTPS (ট্যাব)> "ডিক্রিপ্ট HTTPS ট্র্যাফিক" পরীক্ষা করুন

আমি কারও কাছে মার্জিত সমাধানের আশায় এই থ্রেডে নজর রাখছি।


2

আমি এই একটি উদাহরণ পাওয়া Kubernetes ক্লায়েন্ট যেখানে তারা ব্যবহার করছেন সেটি X509VerificationFlags.AllowUnknownCertificateAuthority ট্রাস্ট স্ব-স্বাক্ষরিত স্ব-স্বাক্ষরিত রুট সার্টিফিকেট করতে। আমি আমাদের PEM এনকোডড রুট শংসাপত্রগুলির সাথে কাজ করার জন্য তাদের উদাহরণটি সামান্যভাবে পুনরায় তৈরি করেছি। আশা করি এটি কাউকে সাহায্য করবে।

namespace Utils
{
  using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Net.Security;
  using System.Security.Cryptography.X509Certificates;

  /// <summary>
  /// Verifies that specific self signed root certificates are trusted.
  /// </summary>
  public class HttpClientHandler : System.Net.Http.HttpClientHandler
  {
    /// <summary>
    /// Initializes a new instance of the <see cref="HttpClientHandler"/> class.
    /// </summary>
    /// <param name="pemRootCerts">The PEM encoded root certificates to trust.</param>
    public HttpClientHandler(IEnumerable<string> pemRootCerts)
    {
      foreach (var pemRootCert in pemRootCerts)
      {
        var text = pemRootCert.Trim();
        text = text.Replace("-----BEGIN CERTIFICATE-----", string.Empty);
        text = text.Replace("-----END CERTIFICATE-----", string.Empty);
        this.rootCerts.Add(new X509Certificate2(Convert.FromBase64String(text)));
      }

      this.ServerCertificateCustomValidationCallback = this.VerifyServerCertificate;
    }

    private bool VerifyServerCertificate(
      object sender,
      X509Certificate certificate,
      X509Chain chain,
      SslPolicyErrors sslPolicyErrors)
    {
      // If the certificate is a valid, signed certificate, return true.
      if (sslPolicyErrors == SslPolicyErrors.None)
      {
        return true;
      }

      // If there are errors in the certificate chain, look at each error to determine the cause.
      if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateChainErrors) != 0)
      {
        chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;

        // add all your extra certificate chain
        foreach (var rootCert in this.rootCerts)
        {
          chain.ChainPolicy.ExtraStore.Add(rootCert);
        }

        chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority;
        var isValid = chain.Build((X509Certificate2)certificate);

        var rootCertActual = chain.ChainElements[chain.ChainElements.Count - 1].Certificate;
        var rootCertExpected = this.rootCerts[this.rootCerts.Count - 1];
        isValid = isValid && rootCertActual.RawData.SequenceEqual(rootCertExpected.RawData);

        return isValid;
      }

      // In all other cases, return false.
      return false;
    }

    private readonly IList<X509Certificate2> rootCerts = new List<X509Certificate2>();
  }
}

1

আমি অনলাইনে একটি উদাহরণ পেয়েছি যা ভালভাবে কাজ করে বলে মনে হচ্ছে:

প্রথমে আপনি একটি নতুন আইসিটিফিকেটপলসি তৈরি করুন

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

public class MyPolicy : ICertificatePolicy
{
  public bool CheckValidationResult(ServicePoint srvPoint, X509Certificate certificate, WebRequest request, 
int certificateProblem)
  {
    //Return True to force the certificate to be accepted.
    return true;
  }
}

তারপরে আপনার http অনুরোধটি প্রেরণ করার আগে কেবল এটি ব্যবহার করুন:

System.Net.ServicePointManager.CertificatePolicy = new MyPolicy();

http://www.terminally-incoherent.com/blog/2008/05/05/send-a-https-post-request-with-c/


1
ServicePointManager.CertificatePolicyঅবচয়
ডটনেট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.