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

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

新規登録して質問してみよう
ただいま回答率
86.12%
WCF

WCFは、.NET Frameworkの提供する機能の一つ。サービス指向アプリケーション構築のためのフレームワークです。ネットワークを通して、異なるコンピュータ上で動くソフトウェア間の通信が可能になります。

HTTPS

HTTPS(Hypertext Transfer Protocol Secure)はHypertext Transfer プロトコルとSSL/TLS プロトコルを組み合わせたものです。WebサーバとWebブラウザの間の通信を暗号化させて、通信経路上での盗聴や第三者によるなりすましを防止します。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

REST

REST(Representational State Transfer)はwebアプリケーションの構築スタイルの一種です。HTTP GET/POSTによってリクエストを送信し、レスポンスはXMLで返されます。SOAPのようなRPCの構築と比べるとサーバからクライアントを分離することが出来る為、人気です。

解決済

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

firstlast
firstlast

総合スコア138

WCF

WCFは、.NET Frameworkの提供する機能の一つ。サービス指向アプリケーション構築のためのフレームワークです。ネットワークを通して、異なるコンピュータ上で動くソフトウェア間の通信が可能になります。

HTTPS

HTTPS(Hypertext Transfer Protocol Secure)はHypertext Transfer プロトコルとSSL/TLS プロトコルを組み合わせたものです。WebサーバとWebブラウザの間の通信を暗号化させて、通信経路上での盗聴や第三者によるなりすましを防止します。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

REST

REST(Representational State Transfer)はwebアプリケーションの構築スタイルの一種です。HTTP GET/POSTによってリクエストを送信し、レスポンスはXMLで返されます。SOAPのようなRPCの構築と比べるとサーバからクライアントを分離することが出来る為、人気です。

2回答

0リアクション

0クリップ

6654閲覧

投稿2019/11/06 07:58

編集2019/11/10 00:27

実現したいこと(目的)

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

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

試したこと

  • WCFを使用
  • RESTFul方式(WebHttpBinding)を使用
  • SSLを使用

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

問題点

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

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

#概要
###通信イメージ
イメージ説明
イメージ説明

###サービス外観
イメージ説明

###サービス利用側外観
イメージ説明

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

該当のソースコード

イメージ説明

サービス

Program.cs

C#

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

C#

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

C#

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

C#

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 でサーバー証明書が正しく構成されていないこと、またはクライアントとサーバーの間でセキュリティ バインドが整合していないことが考えられます。

証明書作成

DOS

自己証明機関の作成 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ページの「注目」タブのフィードに表示されやすくなります。

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

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

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

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

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

適切な質問に修正を依頼しましょう。

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
86.12%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

WCF

WCFは、.NET Frameworkの提供する機能の一つ。サービス指向アプリケーション構築のためのフレームワークです。ネットワークを通して、異なるコンピュータ上で動くソフトウェア間の通信が可能になります。

HTTPS

HTTPS(Hypertext Transfer Protocol Secure)はHypertext Transfer プロトコルとSSL/TLS プロトコルを組み合わせたものです。WebサーバとWebブラウザの間の通信を暗号化させて、通信経路上での盗聴や第三者によるなりすましを防止します。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

REST

REST(Representational State Transfer)はwebアプリケーションの構築スタイルの一種です。HTTP GET/POSTによってリクエストを送信し、レスポンスはXMLで返されます。SOAPのようなRPCの構築と比べるとサーバからクライアントを分離することが出来る為、人気です。