最初の解決策は単純ですが、まだ脆弱性があります。これは、鍵のフィンガープリントが一致することを確認するだけです。しかし、仲介者は仲介接続を確立して独自の鍵交換を作成し、その時点で暗号化鍵を共有して、自分と一致するように自分の鍵交換を作成できます。
根本的な問題は、適切なインフラストラクチャがないことです。自己署名証明書自体を使用しているわけではありませんが、同じ「CA」からの自己署名証明書を使用しているということです。認証局 (自分自身) のルート証明書を作成する必要があり、そのキーから、使用するソフトウェアの CSR を承認する必要があります。これは、すべてのリモート マシンがルート証明書を信頼し、マシンに認証局としてインストールする必要があることを意味します。これを行うことで、アプリケーションで使用される証明書が途中で侵害されるなどの問題を回避できます。ただし、これは、改ざん防止が保証された方法でルート CA 証明書をユーザーに提供できる場合にのみ適用されます。
あなたの問題に対する別の、しかしはるかに抜本的な解決策は、本質的にSSLを捨てるか、その証明書の有効性のために帯域外認証を行うことです。サーバーはクライアントのメッセージを復号化して適切な応答を行うことができるため、クライアントは証明書を検証できます。このようなチャレンジ レスポンス スキームは、サーバーが期待される証明書を持っていること、または少なくとも当事者がそれに対応する秘密鍵を持っていることを数学的/暗号的に証明できます。
Client generates a 256 bit random nonce (RNGCryptoServiceProvider), K_C
Server generates a 256 bit random nonce, K_S
Client encrypts K_C with server's assumed public key, now K_B
Server digitally signs K_S, K_A
Server transmits K_A to client
Client transmits K_B to server
Server decrypts K_B, now N_S
Client verifies K_A using server's assumed public key, if invalid disconnect
Client computes K_A XOR K_C, now Z_C
Server computes N_S XOR K_A, now Z_S
Server transmits Z_S to client
Client verifies Z_S matches Z_C
Client transmits Z_C to server, encrypted using the server's public key
Server decrypts Z_C and verifies that it matches Z_S
すべてがチェックアウトされた場合、チャレンジは完了し、所有している公開鍵の秘密鍵をサーバーが所有していることを保証できます。また、これをショートカットして、サーバーの公開鍵のデジタル署名されたコピーをクライアントに送信することもできません。これは、仲介者がいずれかの側で 2 つのセッションを作成できるためです。クライアントはすでに公開鍵を所有しており、サーバーの公開鍵でノンスを暗号化することにより、有効性に直接挑戦します。これに対する最善の攻撃は、使用されている非対称アルゴリズムの弱点を悪用せずにデータを改ざんできない中間者オブザーバーです。
このスキームのもう 1 つの利点は、個別に認証されているため、この時点で SSL をすべて回避できることです。これで、実際にZ_S == Z_C
有利に使用でき、さらに通信するための合意済みの対称キーとしてZ_S
or (それらは同一です) と見なすことができます。Z_C
私は少し前にこれに似たスキームに関する論文を書き、いくつかの場所で公開されました。おそらく、2007 年付けの「Challenging Authentication-Agreement Protocol (CAAP)」という名前か、2010 年に改訂された私の名前のような名前で見つけることができます。コード例があります。