web-dev-qa-db-ja.com

.netコアの無効なSSL証明書をバイパスします

Httpsサイトに接続する必要があるプロジェクトに取り組んでいます。接続するたびに、そのサイトの証明書は信頼できないサイトからのものであるため、私のコードは例外をスローします。 .netコアhttpで証明書チェックをバイパスする方法はありますか?

以前のバージョンの.NETからこのコードを見ました。私はこのようなものが必要だと思います。

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

ServicePointManager.ServerCertificateValidationCallbackは、.Net Coreではサポートされていません。

現在の状況では、新しい4.1。* System.Net.Httpコントラクト(HttpClient)の新しいServerCertificateCustomValidationCallbackメソッドになります。 .NET Coreチームは、現在4.1契約を最終決定しています。これについては githubで で読むことができます。

CoreFxまたはMYGETフィードのソースを直接使用して、System.Net.Http 4.1のプレリリースバージョンを試すことができます。 https://dotnet.myget.org/gallery/dotnet-core

現在 WinHttpHandler.ServerCertificateCustomValidationCallback Githubの定義

21
Set

このような匿名コールバック関数を使用して、HTTP呼び出しでSSL証明書チェックをオーバーライドできます。

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

さらに、HttpClientにはファクトリパターンを使用することをお勧めします。これは、すぐに破棄されない可能性がある共有オブジェクトであるため、 接続は開いたままになる です。

84
kdaveid

ここで同じ問題の答えを探しに来ましたが、私はWCF for NET Coreを使用しています。同じボートに乗っている場合は、次を使用します。

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

私はこれで解決します:

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);
9
O.Machado

.NET Core 2.2およびDocker Linuxコンテナで自己署名証明書とクライアント証明書認証を使用する場合、同じ問題に直面しました。開発Windowsマシンではすべて正常に機能していましたが、Dockerではこのようなエラーが発生しました。

System.Security.Authentication.AuthenticationException:リモート証明書は検証手順に従って無効です

幸いなことに、証明書はチェーンを使用して生成されました。もちろん、常にこのソリューションを無視して、上記のソリューションを使用できます。

だからここに私の解決策があります:

  1. コンピューターでChromeを使用してP7B形式で証明書を保存しました。

  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);
}
2
DerSkythe