質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.03%

HTTPプロトコルを介して他のコンピューターのアプリケーションとデータを安全に交換したい。(セルフホスト)

受付中

回答 2

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 219

firstlast

score 59

実現したいこと(目的)

HTTPプロトコルを介して他のコンピューター上のアプリケーションとデータを交換したい。
要件:

  • 盗聴、改竄、なりすまし対策が施されている。
  • セルフホストである(IISは使用しない。)

試したこと

  • WCFを使用
  • RESTFul方式(WebHttpBinding)を使用
  • SSLを使用
    但し、サーバー証明書をコンピューターにインポートする手順に未精通なため、サービスのアプリケーションが直接pfxファイルを読み込んで行う方式で実装している。

問題点

エラー(後述)が発生して、データを交換できない。

よろしくお願い致します。

概要

通信イメージ

イメージ説明
イメージ説明

サービス外観

![イメージ説明](2365d4e98d69129cd3192ba7cf05c2b8.png)

サービス利用側外観

イメージ説明

どうぞよろしくお願い致します。

該当のソースコード

イメージ説明

サービス

Program.cs
using System;
using System.Security.Cryptography.X509Certificates;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Security;
using System.ServiceModel.Web;

namespace TestService
{
    class Program
    {
        static WebServiceHost host;

        static void Main()
        {
            //--------------------------バインディング
            WebHttpBinding binding = new WebHttpBinding();
            binding.Security.Mode = WebHttpSecurityMode.Transport;
            binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
            binding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;

            //--------------------------アドレス
            Uri uri = new Uri("https://localhost:5000/TestService");

            //--------------------------サービスの作成とエンドポイントの追加
            host = new WebServiceHost(typeof(TestService));
            ServiceEndpoint se = host.AddServiceEndpoint(typeof(ITestService), binding, uri);

            var behavior = new WebHttpBehavior();
            behavior.FaultExceptionEnabled = false;
            behavior.HelpEnabled = true;
            behavior.DefaultOutgoingRequestFormat = WebMessageFormat.Json;
            behavior.DefaultOutgoingResponseFormat = WebMessageFormat.Json;
            se.EndpointBehaviors.Add(behavior);

            //--------------------------
            ServiceDebugBehavior debug = host.Description.Behaviors.Find<ServiceDebugBehavior>();
            debug.IncludeExceptionDetailInFaults = true;

            ServiceMetadataBehavior metad = new ServiceMetadataBehavior();
            metad.HttpGetEnabled = true;
            metad.HttpsGetEnabled = true;
            host.Description.Behaviors.Add(metad);

            //--------------------------
            var certificate = new X509Certificate2(@"D:\Work\TestService\ServerCert1.pfx", "pswd", X509KeyStorageFlags.UserKeySet);
            host.Credentials.ServiceCertificate.Certificate = certificate;
            host.Credentials.ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;

            //--------------------------
            host.Open();
            Console.WriteLine(string.Format(null, "URL : {0}", uri.ToString()));
            Console.WriteLine("Press <ENTER> to terminate");
            Console.ReadLine();
            host.Close();

        }
    }
}
ITestService.cs
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;

namespace TestService
{
    [ServiceContract]
    interface ITestService
    {
        [OperationContract]
        [WebInvoke(Method = "POST"
                            , RequestFormat = WebMessageFormat.Json
                            , UriTemplate = "/PostMsg"
            )]
        MessageData PostMsg(MessageData msg);
    }

    [DataContract]
    public class MessageData
    {
        [DataMember]
        public string Name { get; set; }

        [DataMember]
        public int Gender { get; set; }

        [DataMember]
        public int Age { get; set; }

    }

}
TestService.cs
using System;

namespace TestService
{
    class TestService : ITestService
    {
        public MessageData PostMsg(MessageData msg)
        {
            Console.WriteLine(string.Format(null, "受信 : {0}", msg.ToString()));

            return new MessageData()
            {
                Name = msg.Name,
                Gender = msg.Gender,
                Age = msg.Age + 1
            };
        }

    }
}

サービス利用側

Form1.cs
using System;
using System.Windows.Forms;
using System.Security.Cryptography.X509Certificates;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Security;
using System.ServiceModel.Web;
using TestService;

namespace TestClient
{
    public partial class Form1 : Form
    {
        WebChannelFactory<ITestService> cf = null;
        ITestService channel = null;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            listBox1.HorizontalScrollbar = true;

            Uri uri = new Uri("https://123.123.123.123:5000/TestService");
            EndpointAddress endpointAddress = new EndpointAddress(uri);

            //--------------------------チャンネル
            cf = new WebChannelFactory<ITestService>(uri);
            WebHttpBinding binding = cf.Endpoint.Binding as WebHttpBinding;
            binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
            binding.Security.Mode = WebHttpSecurityMode.Transport;

            var behavior = new WebHttpBehavior();
            behavior.FaultExceptionEnabled = false;
            behavior.HelpEnabled = true;
            behavior.DefaultOutgoingRequestFormat = WebMessageFormat.Json;
            behavior.DefaultOutgoingResponseFormat = WebMessageFormat.Json;
            cf.Endpoint.Behaviors.Add(behavior);

            var clientCertificate = new X509Certificate2(@"D:\Work\TestService\ServerCert1.pfx", "pswd", X509KeyStorageFlags.UserKeySet);
            cf.Credentials.ClientCertificate.Certificate = clientCertificate;
            cf.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;

            channel = cf.CreateChannel();

        }

        private void button1_Click(object sender, EventArgs e)
        {
            MessageData msg = new MessageData()
            {
                Name = "Taro",
                Gender = 1,
                Age = 3
            };
            MessageData rtn = channel.PostMsg(msg);   //<--------ここでエラー発生
            listBox1.Items.Insert(0, string.Format("Name:{0}, Gender:{1}, Age{2} ", rtn.Name, rtn.Gender, rtn.Age));

        }
    }
}

エラー内容

https://123.123.123.123:5000/TestService/PostMsg に対する HTTP 要求の発行中にエラーが発生しました。この原因としては、HTTPS ケースの HTTP.SYS でサーバー証明書が正しく構成されていないこと、またはクライアントとサーバーの間でセキュリティ バインドが整合していないことが考えられます。

証明書作成
自己証明機関の作成
makecert -n "CN=ServerCN1" -a sha1 -eku 1.3.6.1.5.5.7.3.3 -r -sv ServerCert1.pvk ServerCert1.cer -ss Root -sr localMachine -cy authority -b 11/06/2019 -e 12/31/2019

ソフトウェア発行元証明書の作成
cert2spc ServerCert1.cer ServerCert1.spc

個人情報交換ファイルの作成
pvk2pfx -pvk ServerCert1.pvk -spc ServerCert1.spc -po pswd -pfx ServerCert1.pfx -f

試したこと1

①パワーシェルで、以下のコマンドを実行し、証明書の捺印を取得
Get-PfxCertificate -FilePath ServerCert1.pfx

②トランスポート層で X.509 証明書を使用して認証するクライアントをサポートするために
netsh http add sslcert ipport=0.0.0.0:5000 certhash=9512A6EA3042F7717EA02194097187207136E5FB appid={541eea84-c788-4d23-b6b2-f5210bcdf5c5} clientcertnegotiation=enable
を実行 ※certhashに①で取得した捺印を、appidには、Visual StudioのサービスプロジェクトのプロパティウィンドウにあるGUIDを設定。

===>下記エラー発生
SSL 証明書を追加できませんでした。エラー: 1312
指定されたログオン セッションは存在しません。そのセッションは既に終了している可能性があります。

試したこと2

サービスとクライアントの各ソースコードからセキュリティ関連のコードを除去した場合は、正常なメッセージのやり取りが実現できています。

試したこと3

X509Certificate2メソッドのパスワードの引数をわざと違うものに設定するとちゃんとエラーになります。

補足1

IISでは.pfxファイルをコンピュータにインポートするが、今回の試みでは、X509Certificate2メソッドの引数にファイルを指定している。

補足2

HTTPS通信は、共通鍵暗号方式と公開鍵暗号方式のハイブリッドで成り立っているらしい。

環境

Microsoft Windows 10 Pro (Version 1903)
Microsoft Visual Studio Community 2019
Microsoft .NET Framework 4.7.2

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

+1

セルフホストでSSL結構邪魔くさいですよ。

WCFの基本(念のためです)はこちらで
(docs.microsoft.com)チュートリアル: 基本的な Windows Communication Foundation サービスをホストして実行する

(!)注意
このようなサービスでは、リッスンするコンピューターに HTTP アドレスを登録するための適切なアクセス許可が必要です。 管理者アカウントにはこのアクセス許可がありますが、管理者以外のアカウントの場合は、HTTP 名前空間へのアクセス許可を付与する必要があります。 名前空間の予約を構成する方法については、「HTTP および HTTPS の構成」を参照してください。

ということで以下も参照ください。
(docs.microsoft.com)HTTP および HTTPS の構成

WCF サービスが自己ホスト型の場合は、コマンド ライン ツールを使用して HTTP または HTTPS の設定を構成します。

SSL 証明書の構成
・・・略・・・
手順については、次を参照してください。方法。SSL 証明書でポートを構成します。

ということでこちらも参照ください。
(docs.microsoft.com)方法: SSL 証明書を使用してポートを構成する

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/11/09 00:42

    追加情報4
    HTTPS通信は、共通鍵暗号方式と公開鍵暗号方式のハイブリッドで成り立っているらしい。

    キャンセル

  • 2019/11/09 00:42

    Y.Hさん、アドバイスありがとうございます。質問の方に転記します。

    キャンセル

  • 2019/11/12 16:00

    遠回りでも、戴いた回答のリンク先にあるようなマイクロソフトのドキュメントをまず読むことが重要だと改めて認識しました。まだ全部読めてませんが...^^;

    キャンセル

+1

WCFには明るくないので外しているかもですが、サーバー側でホスティングしようとしているURIは"https://localhost:5000/TestService"であるのに対し、クライアント側は違うURI、"https://123.123.123.123:5000/TestService" でアクセスしようとしています。

"123.123.123.123"は質問投稿用の仮のIPアドレスなのかもしれませんが、いずれにせよlocalhostとは異なります。httpsで運用するサーバーは、アクセスされる際のホスト名を厳密に意識しているはずなので、ここで不一致は良くないのでは。

開発環境上では同一PCということなので、hostsファイルなどを利用してホスト名の部分を合わせてみるか、IPアドレスを合わせてアクセスしてみてください。あるいは簡単に、クライアント側から "https://localhost:5000/TestService" でアクセスできるのであれば、やはりそういうことなのではないかな、と思います。


追記しました:2019-11-12 02:42

先の回答は外していました。くやしかった(?)のと、お手を煩わせてしまった罪滅ぼしに当方でも検証してみました。
結果から書きますと、以下の処置で限定的ながら通信できるようになりました。

  1. 作成した自己証明書の*.pfxファイルをWindows証明書マネージャでインポート
  2. インポートしたWindows証明書マネージャで証明書のサムプリント(拇印)を取得
  3. netshコマンドでポート構成をバインド
  4. サーバー側プログラムで、匿名アクセスを受け付けるよう修正
  5. クライアント側プログラムで、「自己証明書による不正な証明書エラー」によるエラーを回避するよう修正

以下、順にご説明します。

1. 作成した自己証明書の*.pfxファイルをWindows証明書マネージャでインポート

質問者さんの「試したこと1」で、netsh コマンドによるSSL証明書のポート構成のバインド操作ですが、PowerShellのGet-PfxCertificateコマンドで得た拇印ではダメでした。(私自身がこの辺りに不慣れなこともあって)様々なオプションを試しましたが、結局、以下の記事を参考にさせていただき、MMCでの「Windows証明書マネージャcertlm」を用いて自己(オレオレ)SSL証明書ファイルServerCert1.pfxをインポートしました。(すべてデフォルトの指定に沿います)
OnTimeサーバーにSSL証明書を設定する - OnTime Group Calendar

2. インポートしたWindows証明書マネージャで証明書のサムプリント(拇印)を取得

証明書のサムプリント(拇印)は、1.のWindows証明書マネージャで得られたものを利用しました。 (操作方法は記事中に記載されています

3. netshコマンドでポート構成をバインド

証明書のサムプリントの取得部分が違うだけで、あとは質問者さんで行った方法と同じです。

netsh http add sslcert ipport=0.0.0.0:5000 certhash=eae70a1d0144a9a367b4aa810f22b8e95815b602 appid={90164bb5-886c-4536-a752-7fbbf652c070} clientcertnegotiation=enable

netsh http show sslcertでSSL証明書のバインド状況を確認すると、以下のようなものとなりました。

C> netsh http show sslcert
SSL 証明書のバインド: 
------------------------- 



    IP:ポート                     : 0.0.0.0:5000
    証明書ハッシュ                : eae70a1d0144a9a367b4aa810f22b8e95815b602
    アプリケーション ID           : {90164bb5-886c-4536-a752-7fbbf652c070}
    証明書ストア名                : (null)
    クライアント証明書の失効状態の検証: Enabled
    キャッシュされたクライアント証明書のみを使用した失効状態の検証: Disabled
    使用法のチェック              : Enabled
    失効リストの更新を確認する間隔: 0
    URL 取得のタイムアウト        : 0
    Ctl 識別子                    : (null)
    Ctl ストア名                  : (null)
    DS マッパーの使用法           : Disabled
    クライアント証明書のネゴシエート: Enabled
    接続の拒否                    : Disabled
    HTTP2 を無効にする           : Not Set
    QUIC を無効にする            : Not Set
    TLS1.2 を無効にする          : Not Set
    TLS1.3 を無効にする          : Not Set
    OCSP Stapling を無効にする   : Not Set
    トークンのバインドを有効にする         : Not Set
    拡張イベントをログに記録する          : Not Set
    レガシ TLS バージョンを無効にする  : Not Set
    セッション チケットを有効にする        : Not Set
 拡張プロパティ:
    PropertyId                   : 0
    受信ウィンドウ               : 1048576
 拡張プロパティ:
    PropertyId                   : 1
    フレームごとの最大設定       : 2796202
    1 分間の最大設定      : 4294967295

4. クライアント側プログラムで、「自己証明書による不正な証明書エラー」によるエラーを回避するよう修正

もとのサーバー、クライアントプログラムですと、自己証明書を使っていることによる、System.ServiceModel.Security.SecurityNegotiationException 「リモート証明書は無効です。」例外が起きます。

System.ServiceModel.Security.SecurityNegotiationException
  HResult=0x80131501
  Message=機関 'servercn1:5000' との SSL/TLS のセキュリティで保護されているチャネルに対する信頼関係を確立できませんでした。
  Source=mscorlib
  スタック トレース:
   ...(省略)

内部例外 1:
WebException: 接続が切断されました: SSL/TLS のセキュリティで保護されているチャネルに対する信頼関係を確立できませんでした。

内部例外 2:
AuthenticationException: 検証プロシージャによると、リモート証明書は無効です。

これを避けるために、クライアント側に自己証明書であった場合でも、無理やりOKとするよう修正します。
参考:How to accept a self-signed SSL certificate in a WCF client? - Stack Overflow

// MessageData rtn = channel.PostMsg(msg); で送信する前に、リモート証明書の妥当性チェックコールバックを登録
ServicePointManager.ServerCertificateValidationCallback +=
    new System.Net.Security.RemoteCertificateValidationCallback(EasyCertCheck);

// コールバックメソッド
bool EasyCertCheck(object sender, X509Certificate cert,
    X509Chain chain, System.Net.Security.SslPolicyErrors error)
{
    // 自己証明書の場合でも必ずチェックOKとする
    Debug.WriteLine("EasyCertCheck");
    return true;
}

5. サーバー側プログラムで、匿名アクセスを受け付けるよう修正

サーバー側のコードで、binding.Security.Transport.ClientCredentialTypeHttpClientCredentialType.Certificateであると、以下の例外となります。HTTPステータス403なので一応は繋がっているかたちですが、成功としてレスポンスを受信したいので、この設定値を緩やかなものに変えます。

System.ServiceModel.Security.MessageSecurityException
  HResult=0x80131501
  Message=この HTTP 要求は、クライアントの認証方式 'Anonymous' で許可されませんでした。
  Source=WindowsFormsApp1
  スタック トレース:
   ...(省略)

内部例外 1:
WebException: リモート サーバーがエラーを返しました: (403) 使用不可能
//ここを無効にして binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;

// 匿名アクセスを可能とする
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;

6. まとめ

自己証明書用でも構わず処理するようにクライアントを修正したのと、特に匿名アクセスでも受け付けるようにサーバーを修正した点は気になるところですが、一応https接続はできるようになったので、現状の回答として追記させてもらった次第です。

検証した環境は以下となります。。

  • Windows 10 Professional Version 1903 (OSビルド 18362.418)
  • Visual Studio 2017 (Version 15.9.17)
  • .NET Framework 4.5

プログラムの実行状況です。
プログラム実行状況

クライアント側はProgram.csの修正量が多いので、全部掲載します。

using System;
using System.Windows.Forms;
using System.Security.Cryptography.X509Certificates;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Security;
using System.ServiceModel.Web;
using System.Net;
using System.Diagnostics;
using TestService;

namespace TestClient
{
    public partial class Form1 : Form
    {
        WebChannelFactory<ITestService> cf = null;
        ITestService channel = null;
        //private static string pfxPath = @"D:\Work\TestService\ServerCert1.pfx";
        private static string pfxPath = @"C:\project\teratail\221557\ServerCert1.pfx";
        //private static string uris = @"https://123.123.123.123:5000/TestService";
        //private static string uris = @"https://localhost:5000/TestService";
        //private static string uris = @"https://ServerCN1:5000/TestService";
        private static string uris = @"https://192.168.11.103:5000/TestService";

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            listBox1.HorizontalScrollbar = true;

            //Uri uri = new Uri("https://123.123.123.123:5000/TestService");
            Uri uri = new Uri(uris);
            EndpointAddress endpointAddress = new EndpointAddress(uri);

            //--------------------------チャンネル
            cf = new WebChannelFactory<ITestService>(uri);
            WebHttpBinding binding = cf.Endpoint.Binding as WebHttpBinding;
            binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
            binding.Security.Mode = WebHttpSecurityMode.Transport;

            var behavior = new WebHttpBehavior();
            behavior.FaultExceptionEnabled = false;
            behavior.HelpEnabled = true;
            behavior.DefaultOutgoingRequestFormat = WebMessageFormat.Json;
            behavior.DefaultOutgoingResponseFormat = WebMessageFormat.Json;
            cf.Endpoint.Behaviors.Add(behavior);

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

            //var clientCertificate = new X509Certificate2(@"D:\Work\TestService\ServerCert1.pfx", "pswd", X509KeyStorageFlags.UserKeySet);
            var clientCertificate = new X509Certificate2(pfxPath, "pswd", X509KeyStorageFlags.UserKeySet);
            cf.Credentials.ClientCertificate.Certificate = clientCertificate;
            cf.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
            //cf.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.PeerTrust;

            channel = cf.CreateChannel();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            MessageData msg = new MessageData()
            {
                Name = "Taro",
                Gender = 1,
                Age = 3
            };
            try
            {
                MessageData rtn = channel.PostMsg(msg);   //<--------ここでエラー発生
                listBox1.Items.Insert(0, string.Format("Name:{0}, Gender:{1}, Age{2} ", rtn.Name, rtn.Gender, rtn.Age));
            }
            catch (Exception ex)
            {
                Trace.WriteLine(ex.Message);
                throw ex;
            }
        }

        private bool EasyCertCheck(object sender, X509Certificate cert,
            X509Chain chain, System.Net.Security.SslPolicyErrors error)
        {
            Debug.WriteLine("EasyCertCheck");
            return true;
        }
    }
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/11/12 15:40

    大変感謝しております。
    現時点で要望を満たしていなくても、今後の道筋を付けて頂いたように思います。最終的に私の要望自体が無理なことだった結論に至ることもあるかと思います。取り敢えず、今気になっているのは、makecertの ekuスイッチで、生成する証明書の種類(サーバー証明書、クライアント証明書、コード証明書、等)が指定できることです。コード証明書は、ソフトウェア等に電子署名をする際に必要なもののようです。サーバー証明書、クライアント証明書が、今やろうとしていることと、どう絡んでくるか絡まないのか調べて行こうと思っています。

    キャンセル

  • 2019/11/12 17:19

    https://docs.microsoft.com/ja-jp/dotnet/framework/wcf/feature-details/how-to-create-temporary-certificates-for-use-during-development
    これも気になっています。
    ~~~引用開始~~~
    新しい SelfSignedCertificate コマンドレットによって生成される証明書は、テスト目的でのみ提供されます。
    ~中略~
    自己署名証明書を信頼されたルート証明機関ストアに配置すると、展開環境をより厳密にシミュレートする開発環境を作成できます。
    ~~~引用終了~~~

    キャンセル

  • 2019/11/12 17:22 編集

    情報提供ありがとうございます。興味深く思いますが、開発/テスト環境用に特別に設定できるとなると、更に条件が増えることになるので実運用への展開でまた少し苦労しそうですね。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.03%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる
  • トップ
  • C#に関する質問
  • HTTPプロトコルを介して他のコンピューターのアプリケーションとデータを安全に交換したい。(セルフホスト)