web-dev-qa-db-ja.com

asp.net mvc 4アプリケーションでsslプロトコル、暗号、その他のプロパティを確認する

コンプライアンス上の理由により、ウェブサーバーで一部の暗号とSSL2のサポートをオフにする必要があります。これは実際には問題ではありませんが、ウェブサイトへのログインが成功した後、まだTLS 1.2でサーバーに接続していない場合は、ブラウザーでTLS 1.2をオンにすることをお勧めします。だから私が持っている質問は:

IISで実行されているASP.net(MVC 4)アプリケーションへのhttpsリクエストで使用されているプロトコルと暗号をどのように検出できますか?

SCHANNELリクエストをイベントログに記録してからもう一度読み取る方法があることは知っていますが、これは私にとって非常に醜く聞こえます。

System.Net.Security.SslStreamに必要なプロパティがあることを確認しました。例:CipherAlgorithm、HashAlgorithm、KeyExchangeAlgorithm&SslProtocol、しかし、mvc4アプリケーションのコントローラーアクションでこれらのプロパティをどこで取得できるかわかりません。

28
Chief Wiggum

ILSpy によって判断される悪いニュースは、ASP.NET内のどこからでも_System.Net.SslStream_インスタンスにアクセスする方法がないことです。そのクラスは、WCFフレームワークなどによって、ネットワークに対する直接プログラミングに使用されます。 ASP.NETから実行できる最善の方法(IISまたはHttpListenerの上でSystem.WebまたはOWINを使用するかどうか)は、サーバー変数( IISサーバー変数のリストを参照 を取得することです。 _)クライアントとネゴシエートされた安全なトランスポートによって接続が保護されているかどうか。

Webリクエスト中にイベントログからデータを決定論的に読み取る限り...それは恐ろしいようです。ただし、うまくいく場合は、コードを共有してください。 :)

または、下でSslStreamを使用する独自のOwinホスト(別名Webサーバー!)を実装することもできます。多分。 :P SslStreamプログラミングの詳細については、 この記事 を参照してください。

ただし、サーバーで特定のプロトコルをすでにオフにできるため( この記事 のように...)、サイトを2つの異なるサブドメインに設定できます。 _www.example.com_および_secure.example.com_。前者はバニラWebサーバーであり、後者はTLS 1.2接続のみを受け入れるように構成されています。次に、_www.example.com_から提供され、_secure.example.com/securityUpgradeCheck_にAJAXリクエストを送信しようとするブートストラップロジックを記述します(おそらく、スタイルの良いスピナーアニメーションを使用して、「お待ちください。ユーザーを感動させるこの接続」テキスト:))。そのリクエストが成功すると、ユーザーは_secure.example.com_にリダイレクトされます(そのユーザーエージェントは、何らかの理由でユーザーがブラウザー設定を変更しない限り、TLS 1.2をサポートすることがわかっているため、おそらく永久に)。

追加の影響については、ユーザーがセキュリティのアップグレードに気付くように、セキュアドメイン用のEV SSL証明書を注文してください。 :)

更新: SChannel APIを介してこの情報を取得するために、カスタム(ネイティブ)ISAPIフィルター(または拡張)を作成するという理論に基づいて、さらに掘り下げました。 SSPI CtxtHandle構造を返し、カスタムISAPIから呼び出すことができる関数 _HSE_REQ_GET_SSPI_INFO_ を発見したので、最初は希望に満ちていました_EXTENSION_CONTROL_BLOCK_ ServerSupportFunction関数による拡張。このCtxtHandle構造は、SChannelコンテキストを表し、canは、SSL接続レベルの情報を取得できる_SECPKG_ATTR_CONNECTION_INFO_属性への参照を取得します(同じ.NETのSslStreamクラスに表示される情報(私が知る限り)。ただし、残念なことに、 Microsoftはその可能性を予測した と判断し、この情報はクライアント証明書を使用している場合にのみ利用可能です。動作は「仕様による」ものです。

1つの(ネイティブ)SSPI関数 QueryContextAttributes (Schannel) がありました。これは、MSDNを長い間探していたときに、機能することを発見しました。私はまだ試していません。上記のISAPI APIの制限と同じ「設計上の」理由で失敗する可能性があります。ただし、試してみる価値はあります。このルートを探索したい場合は、 ISAPI拡張の例 をご覧ください。実際、このアプローチでは、新しいIIS 7.0+ SDKを使用して、代わりにIISモジュールを記述できる場合があります。

しかし、クライアント証明書を要求する贅沢がなく、そのロングショットが機能しないと仮定すると、2つのオプションしか残せません。

  1. 同じ物理/仮想マシンで実行されているが、異なるポートなどで実行されている別のWebサーバー(Apacheなど)を使用します(コメントでの説明に従って、別のマシンを起動することはできません)。クライアントに情報メッセージのみを提供する場合は、AJAXリクエストと組み合わせたこのアプローチで十分です。はい、別のポートがファイアウォールによってどこかでブロックされている可能性がありますが、それはとにかくオプションの情報メッセージにすぎません。
  2. システムイベントログは、半脆弱なアプローチに依存しています。 Schannelイベントログを有効にする し、イベントログクエリコードを記述して、最後にログに記録されたSchannelイベントと要求を関連付けようとします。イベントログに書き込まれるすべてのものを現在のHTTPリクエストと確実に関連付ける方法を見つける必要があることに注意してください。したがって、可能性がありますISAPIフィルター/拡張またはIISも記述する必要がありますこの場合は、Schannelコンテキストハンドルを見つけるためのモジュール(これは、相関が基づくと仮定しています)。

ちなみに、ロードバランサーはSSLインターセプトを行うように構成されていますか?とにかく、このすべてがとにかく意味がないので...考えてみてください。

PDATE: Schannelロギングを有効にすると、この宝石がネッティングされます:

_<Event xmlns="http://schemas.Microsoft.com/win/2004/08/events/event">
  <System>
    <Provider Name="Schannel" Guid="{1F678132-5938-4686-9FDC-C8FF68F15C85}" /> 
    <EventID>36880</EventID> 
    <Version>0</Version> 
    <Level>4</Level> 
    <Task>0</Task> 
    <Opcode>0</Opcode> 
    <Keywords>0x8000000000000000</Keywords> 
    <TimeCreated SystemTime="2014-08-13T02:59:35.431187600Z" /> 
    <EventRecordID>25943</EventRecordID> 
    <Correlation /> 
    <Execution ProcessID="928" ThreadID="12912" /> 
    <Channel>System</Channel> 
    <Computer>**********</Computer> 
    <Security UserID="S-1-5-18" /> 
  </System>
  <UserData>
    <EventXML xmlns:auto-ns3="http://schemas.Microsoft.com/win/2004/08/events" xmlns="LSA_NS">
      <Type>client</Type> 
      <Protocol>TLS 1.2</Protocol> 
      <CipherSuite>0x3c</CipherSuite> 
      <ExchangeStrength>2048</ExchangeStrength> 
    </EventXML>
  </UserData>
</Event>
_

これは、マネージコードから直接読み取ることができます。残念ながら、UserIDはIISワーカープロセスSIDにのみ対応していると思いますが、何らかの相関ヒューリスティックを思い付くことができると想定して、イベントログを継続的にポーリングしてリストを提供するバックグラウンドスレッドを設定できます。最近確立されたクライアントハンドシェイク(おそらくConcurrentDictionaryを使用)。

そこ。それでおしまい。興味のある調査はもう必要ありません。私はこれで終わりです。 :P

35
Lars Kemmann

まったく同じ問題があるので、興味を持ってこれを読んでください。

この種の情報を照会するために利用可能なパブリックWebサービスが必要であることに気付き、少し調査を行ったところ、次のことがわかりました https://www.howsmyssl.com/s/api.html =

APIは こちら です。

このAPIはクライアント側のJavaScriptから呼び出すことができ、簡単に解析できる標準のJSONを返し、適切なアラートをユーザーに表示します。

また、ログの目的で情報を独自のWebサービスに送信し、その情報を既存のIISログと組み合わせてみることもできます。

あなたが直面する唯一の問題は、第三者に依存することです。これは、独自のサーバーを立ち上げて GitHubで自由に利用できるコード をホストすることで軽減できます。

私たちはこのソリューションに取り組みますので、コードを配置したら、この回答を更新します。

上記の包括的な回答を提供してくれたLarsに再度感謝します。私はその投稿へのコメントとしてこれを追加しましたが、人々がより簡単に見つけられるように、別の回答を作成する価値があると思いました。

5
CarlR

サーバーからネゴシエートされたTLSハンドシェイクをどのように確認しますか? は、ASP.Net MVC/WebAPIでIIS 8.5以降)でこれを取得する方法を持っています。少なくともそれは昨日答えたとき、私と他の何人かのために働いた。