web-dev-qa-db-ja.com

TLS1.2を使用してクライアントをTCPサーバーに接続する

デバイスを.Net(4.5.2)サーバーに接続しようとしています。 TLS 1.2を使用するのは、デバイスによって開かれたTCP接続です。

  • サーバー側では、TCPサーバー:SslStreamラップスルー DotNetty の標準.Net実装があります
  • デバイスで何も変更できません

すべての.Netクライアントは、セキュリティで保護されたTLS接続を使用してサーバーに正常に接続できます。 CURLを試してみても機能しているので、TCPサーバーは正常に機能していると結論付けました。

そこで、(Wiresharkを使用して)動作中のクライアントから送信されたものと、接続できないデバイスから送信されたものを比較しました。私が見つけた重要な違いは、Client Hello TLSメッセージ内に Server Name Extension(SNI) がないことです(デバイスの場合)。

次に試したのは、 Pcap.Net を使用してサーバーにデータを手動で送信することです。つまり、生のバイト配列を使用してTCP SYN/TCP ACK/Client Helloメッセージを手動で送信します。 (サーバーに接続しようとしているデバイスから(Wiresharkのおかげで)取得した生データ)サーバー名拡張機能を追加して、機能しないClient Hello生バイト配列を微調整すると、TLSハンドシェイクが機能することを確認しました。

そのため、SNI拡張機能が含まれていないクライアントと、この情報が存在しない場合にハンドシェイクを拒否するサーバーで問題が発生したことは明らかです。

TCPサーバーがサーバー名拡張子を提供しないクライアントを受け入れるように動作する方法を変更するにはどうすればよいですか?そもそも標準の.Net SslStreamを使用して可能ですか?クラス?

AFAIK、SNI拡張機能は必須ではなく、それを使用するかどうかを決定するのはクライアントの責任であるため、サーバーは理論的にクライアントを受け入れる必要がありますそれなしでこんにちはメッセージ。

どんなポインタでも大歓迎です。

18
ken2k

.Net 4.5.2はTLS1.2をサポートしていますが、デフォルトでは無効になっています。

これを有効にするには、セキュリティプロトコルセットを明示的に定義する必要があります。

System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

詳細については、次のリンクを参照してください https://msdn.Microsoft.com/en-us/library/system.net.servicepointmanager.securityprotocol%28v=vs.110%29.aspx

1
cristallo