it-swarm.com.de

Überprüfen Sie das SSL-Protokoll, die Verschlüsselung und andere Eigenschaften in einer ASP.NET MVC 4-Anwendung

Aus Compliance-Gründen müssen wir die Unterstützung einiger Chiffren und SSL2 auf unseren Webservern ausschalten. Dies ist kein wirkliches Problem, aber wir möchten sie nach der erfolgreichen Anmeldung auf der Website darüber informieren, dass wir empfehlen, TLS 1.2 in ihrem Browser zu aktivieren, falls sie noch keine Verbindung zum Server mit TLS 1.2 herstellen. Die Frage, die ich habe, ist also:

Wie kann ich das Protokoll und die Verschlüsselung erkennen, die in einer https-Anforderung an eine ASP.net (MVC 4) -Anwendung verwendet werden, die in IIS ausgeführt wird?

Ich weiß, dass es Möglichkeiten gibt, die SCHANNEL-Anforderung im Ereignisprotokoll zu protokollieren und sie dann erneut vorzulesen, aber das klingt für mich sehr hässlich.

Und ich habe gesehen, dass der System.Net.Security.SslStream die Eigenschaften hat, die ich benötigen würde, zB: CipherAlgorithm, HashAlgorithm, KeyExchangeAlgorithm & SslProtocol , aber ich bin nicht sicher, wo ich kann Diese Eigenschaften erhalten Sie in meiner Controller-Aktion in einer MVC4-Anwendung.

26
Chief Wiggum

Die schlechte Nachricht ist, wie durch ILSpy festgestellt, dass es keine Möglichkeit gibt, von irgendwo in ASP.NET zu einer Instanz System.Net.SslStream Zu gelangen. Diese Klasse wird für die direkte Programmierung im Netzwerk verwendet, beispielsweise vom WCF-Framework. Das Beste, was Sie mit ASP.NET tun können (unabhängig davon, ob Sie System.Web oder OWIN auf IIS oder HttpListener verwenden), ist, eine Servervariable abzurufen ( siehe Liste der IIS Servervariablen ) ob die Verbindung durch irgendeinen sicheren Transport gesichert ist, der mit dem Client ausgehandelt wurde.

Das deterministische Lesen von Daten aus dem Ereignisprotokoll während einer Webanforderung ... scheint beängstigend. Aber wenn Sie es zum Laufen bringen können, geben Sie bitte den Code weiter. :)

Alternativ können Sie versuchen, einen eigenen Owin-Host (auch bekannt als Webserver) zu implementieren, der SslStream darunter verwendet. Vielleicht. : P Siehe dieser Artikel für eine gründliche Einführung in die Programmierung von SslStream.

Aber da Sie bereits in der Lage sind, bestimmte Protokolle auf Ihrem Server zu deaktivieren (wie in dieser Artikel , nehme ich an) ... Sie könnten Ihre Site in zwei verschiedenen Unterdomänen einrichten, z. www.example.com Und secure.example.com, Wobei ersterer ein Vanilla-Webserver ist und letzterer so konfiguriert ist, dass nur TLS 1.2-Verbindungen akzeptiert werden. Dann würden Sie eine Bootstrapping-Logik schreiben, die von www.example.com Geliefert wird und versucht, eine AJAX -Anforderung an secure.example.com/securityUpgradeCheck Zu senden (möglicherweise mit einer hübsch gestalteten Spinner-Animation und "Bitte warten, versuchen Sie es um diese verbindung zu sichern "text um ihre benutzer zu beeindrucken :)). Wenn diese Anforderung erfolgreich ist, kann der Benutzer zu secure.example.com Umgeleitet werden (wahrscheinlich dauerhaft, da dieser Benutzeragent dann bekanntermaßen TLS 1.2 unterstützt, es sei denn, der Benutzer ändert aus irgendeinem Grund seine Browsereinstellungen).

Bestellen Sie ein EV-SSL-Zertifikat für die sichere Domain, damit Ihre Benutzer das Sicherheitsupgrade bemerken. :)

UPDATE: Ich habe auf der theoretischen Grundlage des Schreibens eines benutzerdefinierten (nativen) ISAPI-Filters (oder einer Erweiterung) noch ein bisschen nachgeschlagen, um über die auf diese Informationen zuzugreifen SChannel API. Zuerst war ich hoffnungsvoll, weil ich eine Funktion entdeckt habe HSE_REQ_GET_SSPI_INFO , die einen SSPI CtxtHandle Struktur, die Sie von einer benutzerdefinierten ISAPI-Erweiterung über die Funktion EXTENSION_CONTROL_BLOCKServerSupportFunction aufrufen können. Wie sich herausstellt, stellt diese CtxtHandle -Struktur einen SChannel-Kontext dar und kann Ihnen einen Verweis auf ein SECPKG_ATTR_CONNECTION_INFO - Attribut geben, mit dem Sie SSL abrufen können Informationen auf Verbindungsebene (die gleichen Informationen, die meines Erachtens in der Klasse SslStream in .NET aufgetaucht sind). Leider hat Microsoft diese Möglichkeit vorweggenommen und entschieden, dass diese Informationen nur verfügbar sind, wenn Sie Client-Zertifikate verwenden. Das Verhalten ist "von Entwurf".

Es gab eine (native) SSPI-Funktion, QueryContextAttributes (Schannel) , die ich bei einer langen Durchsuchung entdeckt habe MSDN, die funktionieren kann . Ich habe es nicht ausprobiert, und es könnte einfach aus demselben "beabsichtigten" Grund fehlschlagen wie die ISAPI-API-Einschränkung, auf die oben verwiesen wurde. Es kann jedoch einen Versuch wert sein. Wenn Sie diese Route erkunden möchten, finden Sie hier ein Beispiel für eine ISAPI-Erweiterung . Tatsächlich können Sie mit diesem Ansatz möglicherweise stattdessen ein IIS - Modul mit dem neueren SDK IIS 7.0+ schreiben.

Vorausgesetzt, Sie haben nicht den Luxus, Client-Zertifikate zu verlangen, und diese lange Wartezeit funktioniert nicht, bleiben nur zwei Optionen.

  1. Verwenden Sie einen anderen Webserver (Apache usw.), der auf derselben physischen/virtuellen Maschine, aber auf einem anderen Port usw. ausgeführt wird (wie in den Kommentaren erläutert, da Sie keine andere Maschine hochfahren können). Wenn Sie dem Client nur eine Informationsnachricht geben möchten, ist dieser Ansatz in Verbindung mit einer AJAX - Anforderung möglicherweise ausreichend. Ja, ein anderer Port könnte irgendwo von einer Firewall blockiert werden, aber hey - es ist sowieso nur eine optionale Informationsnachricht.
  2. Verlassen Sie sich mit dem Systemereignisprotokoll auf die halbversprödete Vorgehensweise. Schannel-Ereignisprotokollierung aktivieren und schreiben Sie dann einen Abfragecode für das Ereignisprotokoll, um zu versuchen, die Anforderung mit dem zuletzt protokollierten Schannel-Ereignis zu korrelieren. Beachten Sie, dass Sie einen Weg finden müssen, um zuverlässig zu korrelieren, was auch immer im Ereignisprotokoll mit der aktuellen HTTP-Anforderung abgelegt wird, sodass Sie möglicherweise auch einen ISAPI-Filter/eine ISAPI-Erweiterung schreiben müssen oder das Modul IIS, um in diesem Fall das Schannel-Kontexthandle zu finden (worauf die Korrelation basieren würde).

Übrigens - ist Ihr Load Balancer so konfiguriert, dass er SSL abfängt? Denn dann ist das Ganze sowieso umstritten ... Nur ein Gedanke zum Überlegen.

UPDATE: Durch Aktivieren der Schannel-Protokollierung wurde dieses Juwel verrechnet:

<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>

Dies kann direkt aus verwaltetem Code ausgelesen werden. Ich denke, die UserID entspricht leider nur der SID des Worker-Prozesses IIS. Unter der Annahme, dass Sie eine Art Korrelationsheuristik entwickeln können, könnten Sie einen Hintergrund-Thread einrichten, um das Ereignisprotokoll fortlaufend abzufragen und eine Liste zu erhalten von kürzlich eingerichteten Client-Handshakes (verwenden Sie möglicherweise ein ConcurrentDictionary).

Dort. Das ist es. Keine neugierigen Nachforschungen mehr für mich. Ich bin fertig. : P

35
Lars Kemmann

Wenn Sie dies mit Interesse lesen, haben wir genau das gleiche Problem.

Mir fiel auf, dass es einen öffentlichen Webdienst geben muss, um diese Art von Informationen abzufragen, und ich habe etwas recherchiert und Folgendes gefunden: https://www.howsmyssl.com/s/api.html

Die API ist hier

Diese API kann von clientseitigem Javascript aus aufgerufen werden und gibt Standard-JSON zurück, das einfach analysiert werden kann und Ihren Benutzern eine geeignete Warnung angezeigt wird. 

Sie können die Informationen auch zu Protokollierungszwecken an Ihren eigenen Web-Service senden und versuchen, die Informationen mit Ihren vorhandenen IIS -Protokollen zu kombinieren.

Das einzige Problem, dem Sie dann gegenüberstehen, ist, sich auf einen Dritten zu verlassen. Dies kann dadurch gemindert werden, dass Sie Ihren eigenen Server aufstellen und den Code hosten, der auf GitHub frei verfügbar ist.

Wir werden an dieser Lösung arbeiten. Sobald ich etwas Code habe, werde ich diese Antwort aktualisieren.

Nochmals vielen Dank an Lars für die umfassende Antwort oben. Ich hätte dies als Kommentar zu diesem Beitrag hinzugefügt, aber ich dachte, es lohnt sich, eine separate Antwort zu erstellen, damit die Leute es leichter finden können.

5
CarlR

Wie überprüfe ich den Negotiated TLS Handshake vom Server? hat den Weg, dies unter IIS 8.5 und höher in ASP.Net MVC/WebAPI zu erhalten. Zumindest funktionierte es für mich und einige andere, als ich gestern darauf antwortete.