1

私は現在、C# クライアントとサーバー アプリケーションの間でステートフルで暗号化された接続を確立するための最良の方法を探しています。最初は IPsec の使用を考えましたが、低レベル (OSI: Internet Layer) で動作するため、プログラム内の機能が必要で OS に依存したくない場合、実装は非常に困難です。

この目的のためにどのような技術をお勧めしますか? .NET (4.5) に既に組み込まれている機能はありますか? 必ずしもステートフルである必要はありません。ある種のハートビートを使用することも有効なオプションです。

4

3 に答える 3

3

独自のプロトコルを作成するのではなく、SSL などの標準プロトコルを使用することをお勧めします。まず、.NET フレームワークがそれをサポートし、その下で実行されるトランスポート プロトコルがステートフル (TCP など) であるため、実装がはるかに簡単になります。次に、安全な暗号化プロトコルを開発することは非常に困難であり、SSL は既に実装されているのに、なぜ車輪を再発明するのでしょうか?

SSL は、PKI (Public Key Infrastructure) を使用して共有対称キーを生成することによって機能します。ハンドシェイクはいくつかのステップで構成されています。最初にクライアントが安全なセッションの要求を送信し、次にサーバーがその証明書で応答します。クライアントは、認証局 (Verisign、Thawte、GeoTrust など) を介してはしごを上ってクロールするか、または既に信頼している場合は、証明書を検証します。サーバーは、自己署名された証明書を受け入れることができます....そして、証明書が信頼できると判断すると、対称キーを生成し、アルゴリズムを選択します(たとえば、AES、3DES、RC4、IDEAなど...)。次に、クライアントは公開鍵で使用されている鍵とアルゴリズムを暗号化し、クライアントはその値をサーバーに送信します。安全なセッションは対称暗号化を使用して続行できます。これははるかに高速です。

SSL 自体は、OSI モデルのトランスポート層で実際に機能するため、ステートフルな方法で使用できます。一方、HTTPS は設計上、ステートフルなプロトコルではありません。HTTPS は HTTP over SSL であるため、要求されているアプリケーション データを保護するために HTTPS で SSL が使用されることを除けば、技術的にはこの 2 つは互いに何の関係もありません。HTTP と同様に HTTPS を使用すると、サーバーにリクエストが送信されると、基本的にユーザーのことは忘れられます (正確にどのように発生するかではありませんが、すべての意図と目的のために、このように考えることができます)。私自身は、ステートフル プロトコルを使用しなければならない状況を回避できるのであれば、HTTPS の使用を好みます。そうする主な理由は、コードを書く必要がなく、SSL の実装で間違いを犯す可能性をなくすためです。

そうは言っても、アプリケーション レベルで HTTP を使用しない独自の SSL サーバーを作成したい場合は、TcpListener クラスと TcpClient クラスを .NET の一部として提供される SslStream クラスと共に使用して、独自の SSL サーバーを作成できます。MSDN には、SSL サーバーとクライアントを作成する方法の良い例があります: http://msdn.microsoft.com/en-us/library/system.net.security.sslstream%28v=vs.110%29.aspx

サイドノート

  • データの転送を保護しても、アプリは保護されません。自動的にセキュリティが確保されると誤解しないでください。
  • 独自のサーバーとクライアントを作成する場合は、opensslを使用して証明書を生成するか、.NET の一部であるmakecertを使用して証明書を作成できます。
于 2013-06-29T10:55:38.307 に答える
1

アプリケーション間で通常の TCP 接続を形成し、単純なパケット プロトコルを記述します (例: 4 バイトはパケット サイズを示し、その後にパケット データが続きます)。

ただし、この基本レベル パケット内のデータは暗号化されています。System.Cryptography.AesManaged

AesManaged を使用してパケットを暗号化するのに問題がある場合は、The Encryptamajigを使用してみてください。それでも問題が解決しない場合は、さらに質問を投稿してください。さらに具体的なヘルプを提供します。

-- 事前に双方にパスワードを知ってもらう (例: 相手に直接パスワードを伝える) か、接続の開始時にパスワードを暗号化せずにすばやく渡す (または、デフォルトで暗号化する) ことができます。既知のパスワード)

必ずしも最良の方法ではありませんが、それでうまくいくはずです。

于 2013-06-29T07:06:41.677 に答える