Pour des raisons de conformité, nous devons désactiver la prise en charge de certains chiffrements et de SSL2 sur nos serveurs Web. Ce n'est pas vraiment un problème, mais nous souhaitons également les informer, après leur connexion réussie au site Web, que nous suggérons d'activer TLS 1.2 dans leur navigateur s'ils ne se connectent pas déjà au serveur avec TLS 1.2. Donc la question que j'ai est:
Comment puis-je détecter le protocole et le chiffrement utilisés dans une demande https à une application ASP.net (MVC 4) s'exécutant dans IIS?
Je sais qu'il existe des moyens de consigner la demande SCHANNEL dans le journal des événements, puis de la relire à nouveau, mais cela me semble très moche.
Et j'ai vu que le System.Net.Security.SslStream a les propriétés dont j'aurais besoin, par exemple: CipherAlgorithm, HashAlgorithm, KeyExchangeAlgorithm & SslProtocol, mais je ne sais pas où je peux les obtenir propriétés dans mon action de contrôleur dans une application mvc4.
La mauvaise nouvelle, telle que déterminée par ILSpy _, est qu'il n'y a aucun moyen de se rendre à une instance System.Net.SslStream
à partir de n'importe où dans ASP.NET. Cette classe est utilisée pour la programmation directe sur le réseau, par exemple via la structure WCF. Le mieux que vous puissiez faire avec ASP.NET (que vous utilisiez System.Web ou OWIN en plus de IIS ou de HttpListener) consiste à obtenir une variable de serveur ( voir la liste des variables de serveur IIS) }. _) pour déterminer si la connexion est sécurisée par le moyen de transport sécurisé négocié avec le client.
En ce qui concerne la lecture déterministe des données du journal des événements lors d'une requête Web ... cela semble effrayant. Mais si vous pouvez le faire fonctionner, veuillez partager le code. :)
Vous pouvez également essayer de mettre en œuvre votre propre hôte Owin (également appelé serveur Web!) Qui utilise SslStream
en dessous. Peut être. : P Voir cet article _ pour une introduction complète à la programmation SslStream
.
Mais comme vous êtes déjà en mesure de désactiver certains protocoles sur votre serveur (comme dans cet article , je suppose) ... vous pouvez configurer votre site sur deux sous-domaines différents, par exemple. www.example.com
et secure.example.com
, où le premier est un serveur Web Vanilla et le dernier est configuré pour accepter uniquement les connexions TLS 1.2. Ensuite, vous écririez une logique d'amorçage qui serait servie à partir de www.example.com
et tenteriez d'envoyer une demande AJAX à secure.example.com/securityUpgradeCheck
(éventuellement avec une animation spinner bien stylée et le texte "Veuillez patienter, tentant de sécuriser cette connexion" pour impressionner vos utilisateurs. :)). Si cette demande aboutit, l'utilisateur peut être redirigé vers secure.example.com
(probablement en permanence, car il est alors reconnu que cet agent utilisateur prend en charge TLS 1.2, sauf si, pour une raison quelconque, l'utilisateur modifie les paramètres de son navigateur).
Pour un impact accru, commandez un certificat SSL EV pour le domaine sécurisé afin que vos utilisateurs remarquent la mise à niveau de la sécurité. :)
UPDATE: J'ai approfondi mes connaissances en écrivant un filtre ISAPI personnalisé (natif) (ou une extension) pour obtenir ces informations via l'API SChannel. Au début, j'avais bon espoir car j'avais découvert une fonction HSE_REQ_GET_SSPI_INFO
qui renverrait une structure SSPI CtxtHandle
et que vous pourriez appeler à partir d'une extension ISAPI personnalisée via la fonction EXTENSION_CONTROL_BLOCK
ServerSupportFunction
. Il s'avère que cette structure CtxtHandle
représente un contexte SChannel et que peut vous fournir une référence à un attribut SECPKG_ATTR_CONNECTION_INFO
avec lequel vous pouvez extraire des informations de niveau de connexion SSL (les mêmes informations que celles présentées dans la classe SslStream
dans .NET, pour autant que je puisse dire). Malheureusement, Microsoft a anticipé cette possibilité et a décidé que ces informations ne sont disponibles que si vous utilisez des certificats clients. Le comportement est "par conception".
Il y avait une fonction SSPI (native), QueryContextAttributes (Schannel)
, que j'ai découverte au cours d'une longue recherche dans MSDN et qui pouvait fonctionner. Je ne l'ai pas essayé et il pourrait tout simplement échouer pour la même raison «de conception» que la limitation de l'API ISAPI liée à ci-dessus. Cependant, cela vaut peut-être la peine d'essayer. Si vous souhaitez explorer cet itinéraire, voici un exemple d'extension ISAPI . En fait, avec cette approche, vous pourriez peut-être écrire un module IIS à la place, en utilisant le nouveau IIS 7.0+ SDK.
Mais si vous n’avez pas le luxe d’exiger des certificats de client et que le plan à long terme ne fonctionne pas, il ne vous reste que deux options.
Soit dit en passant, votre équilibreur de charge est-il configuré pour effectuer une interception SSL? Parce qu'alors tout cela est discutable de toute façon ... Juste une pensée à considérer.
UPDATE: L'activation de la journalisation Schannel a généré cette gemme:
<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>
Cela peut être lu directement à partir du code géré. Je pense que l'ID utilisateur correspond uniquement au SID du processus de travail IIS, malheureusement, mais en supposant que vous puissiez créer une sorte d'heuristique de corrélation, vous pouvez configurer un thread d'arrière-plan pour interroger en permanence le journal des événements et vous fournir une liste. des poignées de main de clients récemment établies (utilisez un ConcurrentDictionary
peut-être).
Là. C'est tout. Pas plus curieux d'investigation pour moi. J'ai fini. : P
En lisant cela avec intérêt, nous avons exactement le même problème.
Je me suis rendu compte qu’il devait exister un service Web public pour interroger ce type d’informations. J’ai fait une petite recherche et trouvé ceci: https://www.howsmyssl.com/s/api.html
L'API est ici
Cette API peut être appelée à partir de Javascript côté client. Elle retourne un JSON standard qui peut être facilement analysé et une alerte appropriée présentée à vos utilisateurs.
Vous pouvez également envoyer les informations à votre propre service Web à des fins de journalisation et essayer de les combiner avec vos journaux IIS existants.
Le seul problème auquel vous êtes confrontés à l’époque est de faire appel à une tierce partie. Cela peut être atténué en mettant votre propre serveur en service et en hébergeant le code disponible gratuitement sur GitHub .
Nous allons travailler sur cette solution, donc une fois le code en place, je mettrai à jour cette réponse.
Merci encore à Lars pour la réponse complète ci-dessus. J'aurais ajouté ceci comme commentaire à ce billet, mais j’ai pensé que cela valait la peine de créer une réponse distincte pour que les gens puissent le trouver plus facilement.
Comment vérifiez-vous la négociation TLS négociée à partir du serveur? a le moyen d'obtenir cela sous IIS 8.5 et versions ultérieures dans ASP.Net MVC/WebAPI. Au moins, cela a fonctionné pour moi et quelques autres quand j'ai répondu hier.